For the complete documentation index, see llms.txt. This page is also available as Markdown.

Server-to-server (S2S)

Configure server-to-server (S2S / M2M) API-key authentication for programmatic clients — CI/CD jobs, automation scripts, and non-human callers — alongside the configured interactive auth mode.

In addition to interactive authentication (Login form, OAuth2/OIDC, LDAP), ODD Platform supports server-to-server (S2S) API-key authentication (also called machine-to-machine (M2M) tokens) for programmatic clients that cannot go through an interactive login — CI/CD jobs, automation scripts, scheduled ingestion pipelines, and any other non-human callers of the Platform API.

How it works

  • A single long-lived token is configured on the platform via auth.s2s.token.

  • Clients present the token in the X-API-Key HTTP header on every request.

  • Requests carrying a valid token run with the built-in ADMIN user and ADMIN role, so they can call any endpoint that admins can call — including the ingestion API, management APIs, and entity mutations.

  • S2S runs alongside the configured interactive auth mechanism, not instead of it. If a request has no X-API-Key header (or the value doesn't match), the filter falls through and the normal auth chain (Login form / OAuth2 / LDAP) handles the request. This means enabling S2S does not affect the user login flow.

S2S is available when auth.type is LOGIN_FORM, OAUTH2, or LDAP. With auth.type: DISABLED, the platform is already open and S2S is not needed.

S2S (X-API-Key) is not the same as the per-collector ingestion token. ODD Platform has two independent, separately-enabled API-auth mechanisms:

  • S2S — this page. A single platform-wide key sent in the X-API-Key header, enabled by auth.s2s.enabled, that authenticates the caller as the built-in ADMIN for any endpoint.

  • Ingestion-token authentication — a per-collector / per-datasource token sent in the Authorization: Bearer <token> header, enabled by auth.ingestion.filter.enabled, that protects the ingestion endpoints only.

They use different headers and different secrets. Sending X-API-Key does nothing if only the ingestion-token filter is enabled; sending Authorization: Bearer does nothing on the S2S path. See Ingestion authentication for the per-collector token mechanism.

Configuration

Property
Default
Description

auth.s2s.enabled

false

Turns the S2S filter on. When true, auth.s2s.token must be set — the platform refuses to start if the token is missing.

auth.s2s.token

(unset)

The shared API key. Any request presenting this value in the X-API-Key header is authenticated as the built-in ADMIN user. Treat this as a high-privilege secret and store it in a secrets manager, not in plaintext config.

auth:
    type: OAUTH2          # or LOGIN_FORM / LDAP
    s2s:
        enabled: true
        token: {long_random_token}
AUTH_TYPE=OAUTH2
AUTH_S2S_ENABLED=true
AUTH_S2S_TOKEN={long_random_token}

Using the token

Send the token in the X-API-Key header on every request:

The same header works for any other Platform API endpoint — for example, listing data sources:

Security considerations

  • The token is a single static string compared for equality — it is not rotated, expired, or scoped. Rotating it requires restarting the platform with a new auth.s2s.token value.

  • Any client that holds the token gets full ADMIN access to the Platform API. Prefer to scope its distribution narrowly: one token per trusted caller tier, not one token shared across unrelated systems.

  • Transport the token only over HTTPS. If the platform is exposed over plain HTTP, anyone on the network path can capture and replay the token.

  • If you only need to authenticate the ingestion pipeline (collectors / push adapters), consider combining S2S with auth.ingestion.filter.enabled: true so the ingestion endpoints remain protected even when S2S is not enabled — see Enable security and the deployment matrix for which endpoints each flag covers.

Operator caveats

auth.s2s.enabled: true has no effect under auth.type: DISABLED. The DISABLED-mode security configuration does not read auth.s2s.enabled, so the S2S filter is never wired into the chain in that mode. The property is accepted in YAML without warning, but X-API-Key requests under DISABLED behave identically to unauthenticated requests (which DISABLED already permits). If you are pre-configuring auth.s2s.enabled for a planned migration to LOGIN_FORM, OAUTH2, or LDAP, the property takes effect only after auth.type flips to one of those modes.

Last updated