> ## Documentation Index
> Fetch the complete documentation index at: https://docs.generalvalidation.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API authentication

> Authenticate a workload to the General Validation API with a Microsoft Entra application token and one of three cumulative application roles.

The General Validation API accepts Microsoft Entra bearer tokens. People use
the app in a browser with a delegated token from their Microsoft sign-in.
Workloads call the API at `https://api.generalvalidation.com` with an
application token issued for the General Validation API and one of the
application roles described below. General Validation does not issue API keys.

Your workload's identity must live in the same Microsoft Entra directory as
your Organization, and that Organization must already be activated by a
person. The API resolves the Organization from the token's verified directory;
a supplied Organization identifier cannot select another Organization's
resources. Machine clients cannot activate an Organization or accept an
invitation. An application role authorizes the workload without a membership
record; a person still needs an active membership to use the app.

## Application roles

Assign the lowest role the workflow needs. Roles are cumulative, and when a
workload holds more than one, the highest recognized role applies.

| Application role | Effective role | What the workload can do |
| - | - | - |
| `GV.APIReader` | Reader | Read Organization, Table Pair, Test, Run, and Result metadata. |
| `GV.APIContributor` | Contributor | Reader access plus creating and updating Table Pairs and Tests and preparing Runs. |
| `GV.APIOwner` | Owner | Contributor access plus Organization administration, the saved Environment reference (not Environment setup in Fabric), and billing. |

The [API reference](https://docs.generalvalidation.com/api/reference.md) states the minimum role for each
operation. No Fabric or OneLake permission is involved: the API holds none,
and an application role grants none. Browsing workspaces and Tables, setting
up the Environment, submitting a Run to Fabric, and reading exact values or
mismatch evidence happen in the app with the signed-in user's own Fabric
access. See [API and automation](https://docs.generalvalidation.com/api/overview.md) for what the API covers
in this release.

## Assign a role to your workload

Use a dedicated identity that your organization owns: a managed identity for
an Azure workload, or an application registration with its own credential. An
Azure subscription role such as Contributor does not grant API access.

Roles are assigned on the General Validation API's service principal in your
directory. You need the API's application (client) ID to assign a role and to
request tokens. The API publishes it in the `entraApplication` security scheme
of its OpenAPI document: `x-gv-audience` is the application ID and
`x-gv-scope` is the scope to request. See
[API and automation](https://docs.generalvalidation.com/api/overview.md) for retrieving the document. If you
cannot retrieve it yet, ask
[support@generalvalidation.com](mailto:support@generalvalidation.com) for the
identifiers.

For an application registration, an Entra administrator adds the General
Validation API's application permission for the chosen role to your
application and grants admin consent.

A managed identity has a service principal rather than an editable
registration, so an administrator assigns the chosen role to that service
principal directly. The following example assigns Reader to an existing
managed identity when run by an administrator who can assign application
roles:

```bash theme={null}
gv_api_client_id="<general-validation-api-client-id>"
gv_caller_object_id="<workload-managed-identity-principal-id>"
gv_api_role="GV.APIReader"

gv_resource_service_principal_id="$(
  az ad sp show --id "$gv_api_client_id" --query id --output tsv
)"
gv_app_role_id="$(
  az rest --method GET \
    --url "https://graph.microsoft.com/v1.0/servicePrincipals/${gv_resource_service_principal_id}?%24select=appRoles" \
    --query "appRoles[?value=='${gv_api_role}' && contains(allowedMemberTypes, 'Application')].id | [0]" \
    --output tsv
)"

az rest --method POST \
  --url "https://graph.microsoft.com/v1.0/servicePrincipals/${gv_caller_object_id}/appRoleAssignments" \
  --headers Content-Type=application/json \
  --body "{\"principalId\":\"${gv_caller_object_id}\",\"resourceId\":\"${gv_resource_service_principal_id}\",\"appRoleId\":\"${gv_app_role_id}\"}"
```

Confirm that both lookups returned the intended IDs before submitting the
assignment.

## Acquire and send a token

For client credentials, request a token from your directory's token endpoint
using the caller's own credential:

```text theme={null}
https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/token
```

Request the scope published as `x-gv-scope`. It names the General Validation
API resource and ends in `/.default`. For an Azure managed identity whose
token request takes a resource or audience rather than a scope, use the same
identifier without the `/.default` suffix. Requesting a scope does not grant
an application role; the assignment above does.

Tokens for the General Validation app itself are delegated user tokens for
people signed in with a browser. The API rejects an application token issued
for the app's audience, so always request the API resource.

Send the token over HTTPS on every request:

```http theme={null}
Authorization: Bearer <access-token>
```

General Validation verifies the token's signature, issuer, audience,
lifetime, and application role, and confirms that the issuing directory is
connected to an activated Organization. Keep token acquisition inside the
workload, and keep credentials and tokens out of logs, screenshots, and
source control. General Validation never receives your workload's credential,
only the token that Microsoft Entra issues.

## Verify access

Start with the access resource, which returns the caller's effective role:

```bash theme={null}
curl --fail-with-body \
  --header "Authorization: Bearer ${gv_access_token}" \
  "https://api.generalvalidation.com/api/v1/organization/access"
```

The response's `principal` reports `kind` as `service_principal` for a
workload and `effectiveRole` as `reader`, `contributor`, or `owner`. A `401`
response with the code [`auth.unauthenticated`](https://docs.generalvalidation.com/errors/auth.unauthenticated)
means the token was not accepted. A `403` response with the code
[`auth.forbidden`](https://docs.generalvalidation.com/errors/auth.forbidden) means the caller lacks the required
role: review the role assignment, then confirm that the workload's directory
is the one where your Organization was activated. Every problem response
carries a `requestId`; include it with the error code when you contact
[support@generalvalidation.com](mailto:support@generalvalidation.com).

## Change or revoke access

Remove the workload's role assignment in your directory to stop newly issued
tokens from carrying that access; a token already issued stays valid until it
expires. Assign a different role the same way to change access. Manage the
identity and its credential through your organization's own workload
lifecycle controls. For what the API returns and never returns, see the data
boundary on [API and automation](https://docs.generalvalidation.com/api/overview.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.