Skip to main content
Outcome: Workloads can call Formal APIs with IdP JWTs and mint connector access tokens.
Prerequisites: A Formal machine user, and an IdP that can mint OIDC JWTs.

Overview

OIDC integrations let external workloads authenticate to the Formal with short-lived identity-provider JWTs. Formal verifies the token, evaluates a claim condition, and maps the caller to a configured machine user. The same trust can mint a short-lived federation token. Use that credential to access data through a Formal — without long-lived Formal API keys or machine access tokens. Use this for remote workloads such as GitHub Actions, GitLab, or Terraform Cloud.
OIDC integrations are separate from SSO. SSO covers human console login. OIDC integrations cover machine authentication to core APIs and optional federated connector access.

How It Works

  1. You create an OIDC integration with an issuer, machine user, and claim condition.
  2. Formal returns an audience value: oidc.formal.ai/<integration_id>.
  3. Your identity provider issues a JWT with that exact aud claim.
  4. The caller presents the JWT as a Bearer token to Formal core APIs.
  5. Formal verifies signature, issuer, audience, time claims, and the claim condition.
  6. The request runs as the integration’s machine user.
  7. Optionally, the caller mints a federation token and connects through a Connector.

Setup in the Formal Console

  1. Go to OIDC Integrations.
  2. Click Create Integration.
  3. Fill in:
    • Name — unique friendly name in your org
    • Issuer — absolute HTTPS issuer URL
    • JWKS URI — optional; leave empty to use OIDC Discovery
    • Machine User — Formal principal that authenticated tokens map to
    • Claim Condition — CEL expression over claims (default true)
    • End-User Email Expression — optional CEL that returns an email string
    • Statusactive or draft (draft disables auth)
  4. Copy the Audience value shown after create.
  5. Configure your identity provider to mint tokens with that audience.
Verify: Create succeeds and the audience appears as oidc.formal.ai/integrationoidc_….

Claim Conditions

Claim conditions are CEL expressions that must return a boolean. Verified JWT claims are available under claims. Examples:
Failed, non-boolean, or invalid expressions deny authentication.

Federated Connector Access

After an OIDC JWT authenticates to the control plane, call CreateFederationToken to mint a short-lived connector credential. Only OIDC-authenticated machine users can call this RPC. API keys and human sessions cannot mint federation tokens.

Mint a federation token

Example response:

Connect through a Connector

Use the response like any Formal username and access token:
Replace <USERNAME> and <FEDERATION_TOKEN> with username and token from the mint response. Protocols that present the Formal JWT can authenticate immediately. Protocols that match stored credentials (for example some MySQL and S3 paths) need the token to sync to the Connector first. Retry briefly if auth fails right after mint.

Token lifetime and claims

Federation token expiry is:
Formal signs the federated JWT with: Upstream OIDC claims are not copied into the federated JWT or synced to Connectors.

End-user attribution

Set End-User Email Expression when the workload acts for a human. The CEL expression runs over verified IdP claims and must return an email string. At mint time, Formal resolves that email to a Formal human user (case-insensitive). Sessions then use the machine user for credentials and the human user as the for policy and audit. Examples:
Leave the expression empty for machine-only trusts. If the expression is set and resolution fails, mint fails closed — no token is issued.

Permissions and Audit

Verified OIDC callers expose claim context to Permissions as:
  • input.user.oidc.integration_id
  • input.user.oidc.issuer
  • input.user.oidc.claims.*
Control-plane audit events also record integration metadata and bounded claim JSON. They never store the raw JWT.

Terraform

You can manage the same resource with Terraform:
Verify:

Troubleshooting

Possible causes:
  • Integration status is draft or deleted
  • Token aud does not exactly match oidc.formal.ai/<id>
  • Issuer or JWKS does not match the integration
  • Claim condition evaluates to false
  • Machine user is inactive or deleted
Fix: Confirm the audience, set status to active, and validate issuer/JWKS/claims.
Possible causes:
  • Issuer is not HTTPS
  • Discovery endpoint is unreachable from Formal
  • JWKS URI is missing when discovery is unavailable
Fix: Set an explicit HTTPS JWKS URI, or fix the issuer discovery document.
Possible causes:
  • Caller used an API key instead of an OIDC Bearer JWT
  • Caller is not a machine user
  • Upstream OIDC JWT is expired
  • End-user email expression failed or matched no Formal human
Fix: Authenticate with a valid OIDC JWT for an active integration. If you set an end-user expression, confirm the claim value and that the human exists in Formal.
Possible causes:
  • Token expired (min(OIDC exp, 1 hour))
  • Wrong Formal username (must be the mint response username)
  • Credential-match protocol used before the token synced
Fix: Mint a fresh token, use the returned username, and retry after a short sync delay for MySQL/S3-style auth paths.

Next Steps

Permissions

Authorize federated callers with claim-aware rules

Machine Users

Create the machine principal OIDC tokens map to

Connectors

Deploy Connectors that accept federation tokens

SSO

Configure human console login separately