> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.mixlayer.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.mixlayer.com/_mcp/server.

# SPIFFE and SPIRE Workload Identity

> Authenticate SPIFFE workloads with X.509-SVIDs or JWT-SVIDs

A SPIFFE workload can authenticate to Mixlayer with the short-lived identity issued through its local Workload API. SPIRE is one implementation of SPIFFE and can issue both X.509-SVID certificates and JWT-SVID tokens.

Use an X.509-SVID when possible. Its private key remains on the workload and Mixlayer verifies proof of possession during the exchange. Use a JWT-SVID when the workload cannot present a client certificate.

## X.509-SVID setup

### 1. Choose a SPIFFE ID

Register the workload in SPIRE with a dedicated SPIFFE ID, such as:

```text
spiffe://example.com/production/model-client
```

Keep separate workloads on separate SPIFFE IDs. The SPIRE registration entry's selectors determine which process can obtain each identity.

### 2. Get the trust bundle

The Mixlayer provider needs the public X.509 bundle for the workload's trust domain. The following SPIRE Agent command is useful for verifying the setup:

```bash
spire-agent api fetch x509 \
  -socketPath /run/spire/sockets/agent.sock \
  -write /run/secrets/mixlayer
```

For the first returned identity, SPIRE writes:

| File           | Contents                                          |
| -------------- | ------------------------------------------------- |
| `svid.0.pem`   | Leaf X.509-SVID followed by its certificate chain |
| `svid.0.key`   | Private key; keep it on the workload              |
| `bundle.0.pem` | Public trust-domain CA bundle                     |

In production, use a SPIFFE Workload API client or SPIFFE Helper so rotated SVIDs and keys replace the files before they expire. A one-time CLI fetch does not keep them current.

### 3. Configure the Mixlayer provider

Create an **X.509** provider in [Workload Identity](https://console.mixlayer.com/app/workload-identity):

1. Add each CA certificate from `bundle.0.pem` as a separate trust anchor.
2. Map the SPIFFE ID from the certificate's URI SAN:

```text
mixlayer.subject = assertion.uri_sans[0]
```

3. Admit only the intended SPIFFE ID:

```cel
mixlayer.subject == "spiffe://example.com/production/model-client"
```

4. Use `true` as the final authorization rule and grant only the permissions the workload needs.

During a SPIRE CA rotation, add every active authority from the new bundle before removing the old authority.

### 4. Exchange the X.509-SVID

Point the exchange at the files kept current by the Workload API client or helper:

**`file=`**

```bash file=exchange-spiffe-x509-svid.sh
export MIXLAYER_CLIENT_CERT="/run/secrets/mixlayer/svid.0.pem"
export MIXLAYER_CLIENT_KEY="/run/secrets/mixlayer/svid.0.key"

MIXLAYER_ACCESS_TOKEN=$(
  jq -n \
    --arg provider "$MIXLAYER_IDENTITY_PROVIDER_ID" \
    '{
      grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
      subject_token_type: "urn:mixlayer:params:oauth:token-type:mtls-x509",
      identity_provider_id: $provider
    }' |
  curl --fail-with-body --silent --show-error \
    --cert "$MIXLAYER_CLIENT_CERT" \
    --key "$MIXLAYER_CLIENT_KEY" \
    https://api.mixlayer.com/v1/workload_identity/token \
    -H "Content-Type: application/json" \
    --data-binary @- |
  jq -er .access_token
)
```

See [X.509 workload identity](/workload-identity-x509) for certificate-chain requirements and CA rotation guidance.

## JWT-SVID alternative

JWT-SVIDs are bearer tokens and can be replayed if exposed. Request a token for Mixlayer alone, keep its lifetime short, and do not log it.

### 1. Expose OIDC discovery

Set SPIRE Server's `jwt_issuer` to a publicly reachable HTTPS origin, then expose the SPIRE OIDC Discovery Provider at that origin:

```hcl
server {
  jwt_issuer = "https://oidc.example.com"
}
```

Set `set_key_use = true` in the OIDC Discovery Provider so its JWKs advertise `use: "sig"`. Mixlayer must be able to retrieve `/.well-known/openid-configuration` and the advertised JWKS as SPIRE rotates signing keys. Keep the server setting, discovery document, and JWT `iss` claim identical.

### 2. Configure the Mixlayer provider

Create an **OIDC** provider with:

| Setting          | Value                                 |
| ---------------- | ------------------------------------- |
| Issuer URI       | The SPIRE OIDC Discovery Provider URL |
| Allowed audience | `https://api.mixlayer.com`            |
| JWKS source      | OIDC discovery                        |

Map and restrict the SPIFFE ID carried in `sub`:

```text
mixlayer.subject = assertion.sub
```

```cel
mixlayer.subject == "spiffe://example.com/production/model-client"
```

### 3. Request and exchange a JWT-SVID

Request one audience and extract the first identity returned by SPIRE:

**`file=`**

```bash file=get-spiffe-jwt-svid.sh
export MIXLAYER_SUBJECT_TOKEN=$(
  spire-agent api fetch jwt \
    -socketPath /run/spire/sockets/agent.sock \
    -audience https://api.mixlayer.com \
    -output json |
  jq -er '.[0].svids[0].svid'
)
```

If the workload is entitled to multiple identities, pass `-spiffeID` with the intended SPIFFE ID instead of relying on the first result. Then follow the [shared OIDC exchange example](/workload-identity-federation#exchange-an-oidc-token).

## Use the Mixlayer token

Both paths return a normal short-lived Mixlayer bearer token:

```bash
curl https://mixlayer.ai/v1/models \
  -H "Authorization: Bearer $MIXLAYER_ACCESS_TOKEN"
```

Refresh the external SVID and exchange it again before the Mixlayer token expires. Do not send the X.509-SVID or JWT-SVID on normal inference requests.