Skip to content

Authentication and authorization: OIDC and JWT

Authentication establishes who is making a request; authorization decides what they may do. In modern platforms, identity comes from a central identity provider through OpenID Connect and OAuth 2.0, carried to each service as a signed token, often a JWT.

Before reading

no other page. Basic familiarity with HTTP and web logins helps.

Why it matters

A data platform has many entry points: query engines, catalogs, APIs, notebooks, BI tools, pipelines. If each manages its own users and passwords, access cannot be granted, reviewed or revoked consistently. With one identity provider and standard tokens, every component can verify who is calling and apply the same rules.

How it works

Authentication (authn) answers "who are you?": a person logs in, a service proves it holds a secret. Authorization (authz) answers "may you do this?": read this table, call this endpoint. They are separate steps, often in separate systems. A valid identity does not imply any permission.

OAuth 2.0 is a framework for issuing access tokens: credentials that let a client call an API on someone's behalf, with limited scope and lifetime. OpenID Connect (OIDC) is a layer on top of OAuth 2.0 that adds login: an ID token that tells the client who the user is. The identity provider (IdP), such as Microsoft Entra ID, Okta or Keycloak, issues both.

Different clients use different flows. A person logging into a web app uses the authorization code flow: the app redirects the browser to the IdP, the user signs in there, and the app exchanges a one-time code for tokens. PKCE, a proof that the same client started and finished the flow, protects the exchange; it is required for public clients such as browser and mobile apps, and recommended for all others. A pipeline or service with no user present uses the client credentials flow: it authenticates with its own client ID and secret, or a certificate, and receives a token as itself. Tools on devices without a browser, such as command-line clients, can use the device authorization flow. Refresh tokens let clients obtain new access tokens without asking the user to sign in again.

sequenceDiagram
  participant A as Analyst in a BI tool
  participant I as Identity provider
  participant E as Query engine
  A->>I: Sign in (authorization code flow with PKCE)
  I-->>A: ID token and access token (JWT)
  A->>E: Query, with access token
  E->>E: Verify signature, issuer, audience, expiry
  E->>E: Authorize: may this user read shop.clean_orders?
  E-->>A: Rows, or access denied

A signed JSON Web Token (JWT) has three parts separated by dots: a header, a payload of claims and a signature, each base64url-encoded. Standard claims include iss (who issued it), sub (whom it is about), aud (which service it is for), exp (when it expires) and iat (when it was issued). IdPs add claims such as scope, groups, roles or email. A service verifies a JWT without calling the IdP: it checks the signature with the IdP's public keys, published as a JSON Web Key Set (JWKS), and checks that the issuer, audience and expiry are right. The payload is encoded, not encrypted: anyone holding the token can read it, so it must not contain secrets.

Service accounts are identities for non-human clients: pipelines, connectors, scheduled jobs. Each should have its own identity with only the permissions it needs, so that its actions are traceable and its access can be revoked without affecting others. When a service acts for a user, for example an API querying the engine on behalf of the person who called it, the user's identity should be passed on, often through token exchange, so that the engine authorizes the user and not the service.

Key terms

  • Authentication: verifying who is making a request.
  • Authorization: deciding whether a request is allowed.
  • Identity provider: the service that authenticates users and issues tokens.
  • OAuth 2.0: a framework for issuing access tokens to clients.
  • OpenID Connect: an identity layer on OAuth 2.0 that adds login and ID tokens.
  • JWT: a signed token carrying claims, verified with the issuer's public keys.
  • Client credentials flow: how a service obtains a token as itself.
  • Service account: an identity for a non-human client.

Example

Two decoded token payloads in the shop, simplified.

An analyst signed in through the BI tool:

{
  "iss": "https://idp.example.com",
  "sub": "u-4821",
  "aud": "query-engine",
  "email": "[email protected]",
  "groups": ["analysts", "region-eu"],
  "iat": 1793257200,
  "exp": 1793260800
}

The nightly pipeline, using client credentials:

{
  "iss": "https://idp.example.com",
  "sub": "svc-orders-pipeline",
  "aud": "query-engine",
  "scope": "pipeline",
  "iat": 1793242800,
  "exp": 1793246400
}

Both were issued on 29 October 2026 and are valid for one hour. The engine accepts them because they are signed by the IdP, meant for it and not expired. What each may do is decided next, from sub, groups and scope, by the engine's authorization rules.

Pitfalls

  • Treating authentication as authorization. A valid token proves identity, not permission.
  • Not checking the audience. A token issued for one service is then accepted by another.
  • Long-lived tokens or shared secrets. Prefer short expiry, refresh tokens and one identity per service.
  • Secrets in the JWT payload. It is readable by anyone who holds the token.
  • Trusting the token's alg header. Accept only the signing algorithms you expect, and never none.
  • Services querying as themselves for users. Every user then gets the service's access, and audit logs show only the service.

Learn more

  • OpenID Connect Core 1.0: https://openid.net/specs/openid-connect-core-1_0.html
  • RFC 7519, JSON Web Token: https://www.rfc-editor.org/rfc/rfc7519
  • RFC 9700, OAuth 2.0 Security Best Current Practice: https://www.rfc-editor.org/rfc/rfc9700

RBAC and ABAC · Catalogs · Data APIs and the backend-for-frontend pattern · Agents and MCP