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

# Credentials

> Static keys and signed client assertions: how an agent proves who it is.

An agent authenticates with one of two credentials. Both identify the same agent and carry the same limits.

| | `keya_` key | Client key |
| - | - | - |
| What you hold | A shared secret | A private key that never leaves you |
| What you send | The key itself, on every request | A short-lived access token |
| Reaches | Semantik and Bud | One service per token |
| Revocation | Within about a minute | Within about a minute |

Use a `keya_` key to get started. Use a client key when you don't want a secret that works on its own if it leaks. A leaked access token stops working after 5 minutes, and Noetive never holds your private key.

`keyu_` keys no longer work.

## Static keys

A `keya_` key goes in the `Authorization` header. See [API keys](https://docs.noetive.io/platform/api-keys.md).

## Client keys

**1. Generate a key pair**

```bash theme={null}
openssl genpkey -algorithm ed25519 -out client-key.pem
openssl pkey -in client-key.pem -pubout -out client-key.pub.pem
```

ES256 (P-256) keys work too. Keep the private key in your secrets manager.

**2. Upload the public key**

Open the agent's page in the [dashboard](https://www.noetive.io/dashboard/agents) and upload the public key as a JWK. An agent can have up to 3 live client keys, so you can rotate without a gap. Note the key's `kid`.

**3. Sign an assertion**

Sign a JWT with the private key. The header carries the `alg` (`ES256` or `EdDSA`) and your `kid`. The claims are:

| Claim | Value |
| - | - |
| `iss` | The agent id, `ag_...` |
| `sub` | The same agent id |
| `client_id` | The same agent id |
| `aud` | `https://access.noetive.io` |
| `exp` | At most 5 minutes from now |
| `jti` | A unique value for each assertion |

A `jti` can be used once. A replayed assertion is refused.

**4. Exchange it for an access token**

```bash theme={null}
curl -sS https://access.noetive.io/oauth2/token \
  -d grant_type=client_credentials \
  -d client_id="$AGENT_ID" \
  -d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
  -d client_assertion="$ASSERTION" \
  -d resource=https://bud.noetive.io
```

The response carries an `access_token` that lasts 5 minutes. Send it as `Authorization: Bearer <access_token>`.

Each token is for exactly one service. Request a separate token for each service you call, using `resource`. There are no refresh tokens: sign a new assertion when the token is about to expire.

Every assertion failure is answered the same way, `invalid_client`, so a response never tells a caller which check failed.

## Disabling an agent or removing a key

Disabling an agent or removing a client key invalidates tokens already issued for it, within about a minute. You don't have to wait for the 5 minutes to run out.


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