> 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.

# X.509 Workload Identity

> Authenticate a workload with a client certificate

X.509 workload identity federation exchanges a verified client-certificate identity for a short-lived Mixlayer access token. The certificate is required only for the exchange; use the returned bearer token for subsequent Mixlayer API requests.

## Before you begin

You need:

* A root CA certificate in PEM format.
* Any intermediate CA certificates needed to build the chain.
* A client certificate and its private key on the workload.
* Permission to manage workload identity providers in your Mixlayer organization.

Keep the private key on the workload. Mixlayer provider configuration contains public CA certificates only.

| Certificate material | Purpose                                                                                  |
| -------------------- | ---------------------------------------------------------------------------------------- |
| Trust anchor         | Root CA that Mixlayer trusts for this provider                                           |
| Intermediate CA      | Builds a path from the client certificate to a trust anchor; it is not trusted as a root |
| Client certificate   | Identifies the workload and is presented during token exchange                           |
| Private key          | Proves possession of the client certificate; never upload it to Mixlayer                 |

## Choose the workload identity

Mixlayer derives these assertion fields from the verified leaf certificate:

| Assertion                      | Value                                  |
| ------------------------------ | -------------------------------------- |
| `assertion.subject_dn`         | Certificate subject distinguished name |
| `assertion.issuer_dn`          | Certificate issuer distinguished name  |
| `assertion.serial_number`      | Lowercase hexadecimal serial number    |
| `assertion.sha256_fingerprint` | Lowercase SHA-256 fingerprint          |
| `assertion.valid_not_before`   | RFC 3339 validity start                |
| `assertion.valid_not_after`    | RFC 3339 validity end                  |
| `assertion.uri_sans`           | URI subject alternative names          |
| `assertion.dns_sans`           | DNS subject alternative names          |

Prefer a stable URI SAN issued by a controlled certificate profile. A fingerprint identifies one certificate and therefore requires a policy update whenever that certificate is renewed.

The following policy assumes each client certificate contains one URI SAN:

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

Restrict admission to the expected workload:

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

Use a final authorization rule such as:

```json
{
  "condition": "true",
  "permissions": ["inference"]
}
```

## Create the provider

#### Console

Open [Workload Identity](https://console.mixlayer.com/app/workload-identity), select **New provider**, and choose **X.509**.

1. Enter a descriptive name.
2. Add each root CA as a separate **Trust anchor certificate**.
3. Add any intermediate CA certificates needed for chain construction.
4. Map `mixlayer.subject` to the certificate identity selected above.
5. Add an admission condition and least-privilege fallback permissions.
6. Create the provider and record its `wi_...` provider ID.

Add one PEM certificate per field. Do not include a private key or concatenate unrelated roots into one field.

#### API

This example reads the CA files without putting private material into shell arguments. It creates the provider inactive so you can review the trust and policy configuration before enabling exchanges.

**`file=`**

```bash file=create-x509-workload-identity-provider.sh
jq -n \
  --rawfile root_ca root-ca.pem \
  --rawfile intermediate_ca intermediate-ca.pem \
  '{
    name: "production-x509",
    active: false,
    attribute_transformations: {
      "mixlayer.subject": "assertion.uri_sans[0]"
    },
    attribute_condition: "mixlayer.subject == \"spiffe://example.com/production/model-client\"",
    authorization_rules: [
      {condition: "true", permissions: ["inference"]}
    ],
    config: {
      type: "x509",
      trust_anchors: [$root_ca],
      intermediate_cas: [$intermediate_ca]
    }
  }' |
curl --fail-with-body https://api.mixlayer.com/v1/organizations/$MIXLAYER_ORG_ID/workload_identity/providers \
  -H "Authorization: Bearer $MIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @-
```

If the client chains directly to the root, omit `--rawfile intermediate_ca ...` and use `intermediate_cas: []`.

After the certificate trust configuration is ready, set the provider to **Active** in the console.

## Present the certificate chain

The certificate file passed by the workload should contain the leaf certificate first, followed by its intermediate chain. Do not include the root certificate.

```text
-----BEGIN CERTIFICATE-----
...leaf client certificate...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...intermediate CA certificate...
-----END CERTIFICATE-----
```

Export the client paths and provider ID:

```bash
export MIXLAYER_IDENTITY_PROVIDER_ID="wi_..."
export MIXLAYER_CLIENT_CERT="/run/secrets/mixlayer/client-chain.pem"
export MIXLAYER_CLIENT_KEY="/run/secrets/mixlayer/client-key.pem"
```

## Exchange the certificate identity

**`file=`**

```bash file=exchange-x509-workload-identity.sh
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
)
```

The JSON body does not contain a `subject_token`; the client certificate is the external credential.

Use the resulting token with the normal bearer header. You do not need to send the client certificate again:

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

## Certificate requirements and rotation

Mixlayer validates the certificate path, CA constraints, validity period, and client-authentication usages. The leaf must not be a CA. If Key Usage is present it must allow digital signatures; if Extended Key Usage is present it must allow client authentication.

Mixlayer does not fetch certificate revocation lists or perform OCSP checks. Use short-lived client certificates and deactivate the provider or remove a compromised trust anchor when revocation is required.

During CA rotation, configure both old and new trust anchors before issuing certificates from the new CA. Remove the old anchor after every workload has rotated. The Mixlayer access token expires after at most one hour and never outlives the client certificate.