> ## 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 to the General Validation SaaS API with Microsoft Entra bearer tokens and least-privilege application roles.

General Validation API v1 accepts Microsoft Entra bearer tokens. Human users
sign in to the hosted application with the API's delegated `GV.Access` scope.
Workloads use application tokens and the API roles described below. General
Validation does not issue API keys or use browser-session cookies for API access.

The hosted application and API have **separate Entra registrations**. The API
client ID identifies the resource your workload calls. The browser application's
client ID is not the API audience.

Your Organization must already be activated in the caller's Entra directory.
General Validation resolves the Organization from the token's verified tenant;
a supplied Organization ID cannot select another tenant's resources. Machine
clients cannot activate an Organization or accept a person's invitation.

## API roles

Assign the lowest cumulative application role the workflow needs on the General
Validation API's service principal in your directory:

| Application role    | Effective access                                                                                            |
| ------------------- | ----------------------------------------------------------------------------------------------------------- |
| `GV.APIReader`      | Read permitted configuration, readiness, capabilities, Runs, and result metadata.                           |
| `GV.APIContributor` | Reader access plus declared authoring, discovery, preparation, and execution operations.                    |
| `GV.APIOwner`       | Contributor access plus declared Organization, membership, source, environment, and billing administration. |

The [endpoint reference](/api/reference) states the minimum role for each
operation. Contributor includes Reader; Owner includes both. The highest
recognized assignment applies, so one appropriate role is sufficient.

Application roles authorize a workload without a human membership record.
Delegated users instead need an active Organization membership with the
operation's corresponding Reader, Contributor, or Owner role.

## Set up an API caller

### 1. Record the API identifiers

Obtain the following nonsecret values from your Organization's API connection
configuration or General Validation support:

* The **General Validation API origin**, separate from the browser app origin.
* The **API application client ID**, separate from the browser app client ID.
* Your Organization's **Microsoft Entra directory (tenant) ID**.

The authenticated API document at `<API origin>/openapi.json` publishes its
configured server and authentication metadata. In
`components.securitySchemes.entraApplication`, `x-gv-scope` supplies the
client-credentials scope. Remove its `/.default` suffix to obtain the resource
URI for managed-identity activities. The
[API guide](/api-and-automation#retrieve-the-deployed-contract) shows how
to retrieve it after authenticating.

### 2. Select and authorize the workload

Use a dedicated customer-owned identity: a managed identity for an Azure
workload, or a workload application using federation, a certificate, or a
customer-managed credential.

For a workload application, an Entra administrator adds the General Validation
API's **Application permission** to the caller and grants admin consent. Choose
one role from the table above.

A managed identity has a service principal rather than an editable app
registration. An administrator assigns the selected API application role
directly to that service principal. For example, the following assigns Reader
to an existing managed identity when run by an administrator authorized to
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}\"}"
```

Verify that both lookups returned the intended IDs before submitting the
assignment. For an ADF pipeline that starts validation and polls the Run,
assign `GV.APIContributor` to the orchestration factory's system-assigned
identity. A generic Azure subscription Contributor role does not grant API
access.

### 3. Acquire and send a token

For client credentials, use your Organization's tenant-specific authority:

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

Request this scope using the caller's own credentials:

```text theme={null}
api://<general-validation-api-client-id>/.default
```

For an Azure managed-identity activity whose setting is named **Resource** or
**Audience**, use `api://<general-validation-api-client-id>` without
`/.default`. The resulting Entra v2 application token must have `idtyp: app`
and the API's bare client-ID GUID in `aud`. Requesting a scope does not grant
an application role.

Send the token over HTTPS to the API origin:

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

General Validation verifies signature, issuer, audience, lifetime, application
identity, role, and the activated Organization's directory. Keep token
acquisition in the workload process and credentials out of logs, screenshots,
and source control.

### 4. Verify access

Start with the capabilities resource:

```bash theme={null}
curl --fail-with-body \
  --header "Authorization: Bearer ${gv_access_token}" \
  "${gv_api_origin}/api/v1/installation/capabilities"
```

Set `gv_api_origin` to the API origin with no trailing slash. The response
reports the caller's effective role and current API limits. A `401` means
authentication failed. A `403` can mean the verified directory is not connected
to an activated Organization or the caller lacks the required access; follow
the returned problem code and detail.

## Change or revoke access

Remove the workload's application-role assignment to stop newly issued tokens
from granting that access after Entra propagation. Previously issued tokens
can remain valid until expiry. Manage the caller identity and its credentials
through your organization's workload lifecycle controls.

Customer execution callbacks use a separate, environment-bound identity and
purpose. Their result-delivery permission does not grant ordinary API access.
The API roles above also do not grant a workload access to exact values or row
evidence in customer storage. See [security and the data boundary](/security-and-data-boundary).
