Guide

API key

An AEP Service can issue an API key after enrollment. The Agent uses that key in the exact HTTP header returned by Grant; AEP defines no default API-key header.

When an API key fits

The api-key grant type lets a Service use its existing header-based API-key authentication after an Agent proves its AEP identity. Grant issues the key; later protected-resource requests present it without a new client assertion for each request. The key is a reusable bearer secret, so the Agent must protect it and the Service must be able to revoke it. The Agent still uses a baseline AEP client assertion for Grant and Revoke.

Request and store the issued key

After enrollment, the Agent sends Grant with a fresh baseline assertion using op=grant, a non-empty Idempotency-Key, and grant_type equal to api-key. It may request Service-defined scopes or supply an optional display label; the Service may ignore the label and may grant fewer scopes than requested. This request uses an illustrative /aep/ endpoint base:

POST /aep/grant HTTP/1.1
Host: api.example.com
Content-Type: application/aep+json
Authorization: AEP <jwt>
Idempotency-Key: 8709695d-6d79-49b4-a7ab-ae5636fed341

{"grant_type":"api-key","requested_scopes":["read"]}

The Service returns the opaque key, its expiry, the selected header, and a stable credential_id. Granted scopes may also be present. These values are illustrative, not credentials to copy:

{
  "api_key": "aep_example_7Jm5xQ2pL9vN4sR8tW6yB3kZ0",
  "credential_id": "key_example_123",
  "expires_at": "2027-01-01T00:00:00Z",
  "header": "x-service-key",
  "scopes": ["read"]
}

The Agent stores api_key as a secret with the Service DID, header, expires_at, any granted scopes, and credential_id. The ID identifies the issued key for management; it is not the value presented to a resource. The expiry is an RFC 3339 timestamp. Missing, null, or empty scopes means the key has no scope-limited authorization; it does not guarantee access to every application action.

The Service must issue expiring keys with at least 128 bits of entropy and store only salted hashes or equivalent one-way verifiers, not raw key values. Key values use visible ASCII but exclude whitespace, control characters, double quotes, commas, semicolons, and backslashes to avoid HTTP header parsing ambiguity.

Use the returned header exactly

For a protected request that accepts api-key, the Agent sends the key in the header returned for that credential. In this example, the Service chose x-service-key:

GET /v1/reports/123 HTTP/1.1
Host: api.example.com
x-service-key: aep_example_7Jm5xQ2pL9vN4sR8tW6yB3kZ0

The same key in a different field is not valid API-key presentation. The Agent must not invent a generic API-key scheme in Authorization or AEP-Authorization; the dedicated AEP carrier does not apply to this grant type. The Service validates only its selected API-key header. If no other AEP credential is presented, a missing key in that header results in authentication_required; an expired, revoked, unknown, malformed, or wrong-Agent key in the selected header results in not_recognized. Authentication still does not guarantee application authorization.

Expire or revoke the key

The Agent stops presenting the key at expires_at and never sends it to another Service or across an origin-changing redirect. Neither Agent nor Service should log the raw key. If it may have been disclosed, the Agent calls Revoke with a fresh baseline assertion and removes the local copy after success.

A Revoke request with grant_type equal to api-key invalidates all API keys of this type issued to the authenticated Agent. To target only one credential_id, the Service must advertise supports_per_credential_revoke as "true" for api-key; otherwise the Agent uses grant-type or all-grant-types Revoke. Continue to Grant and Revoke for the common command contract, or Revoke credentials for choosing a revocation scope.