Configure Sign-On

Connect Tektona to your identity provider, with a worked Microsoft Entra ID example.

Tektona signs users in with OIDC. How you connect your provider depends on what you need: a console your people log in to, an API your pipelines call, or both.

The charts are an early draft

This page describes the self-hosted charts. Pin them to a release tag, and read the release notes before an upgrade.

Pick a model

You needModel
Your provider is the only one, and it speaks OIDCDirect
Several providers, or SAML or LDAP, or self service registrationFederated
Local accounts and passwords next to your providerFederated

Direct points Tektona at your provider. Users sign in at the provider and come back to the console. Nothing sits in between. Microsoft Entra ID, Okta, Keycloak and Authentik all work.

Federated puts Zitadel between your provider and Tektona. Zitadel serves the sign-in pages, and the console shows one button per connected provider. Take this when you need SAML or LDAP, several providers at once, self service registration, or password and passkey accounts beside your provider.

Both models serve API tokens the same way.


Direct with Microsoft Entra ID

Your staff sign in with their work account, and no other component sits between Tektona and Entra ID. The same three URLs also let a pipeline or a service principal exchange a provider token for a Tektona session.

Register the console in Entra ID

Open App registrations, then New registration.

  • Name: Tektona
  • Supported account types: accounts in this organizational directory only
  • Redirect URI: platform Web, value https://<your app host>/api/auth/callback

Record the Application (client) ID and the Directory (tenant) ID. Add a client secret under Certificates & secrets and record the value.

Under API permissions, add the Microsoft Graph delegated permissions openid, profile, email and User.Read, then grant admin consent.

Entra ID must return a verified email. Confirm that the accounts carry one.

For a pipeline that calls the API, also open Expose an API, set the application ID URI to api://<client id>, and add a scope. A token that Entra ID issues for Microsoft Graph cannot be verified by anyone else.

Set the chart values

Read the URLs from the discovery document at https://login.microsoftonline.com/<tenant>/v2.0/.well-known/openid-configuration.

values-control-plane.yaml
auth:
  issuer: "https://login.microsoftonline.com/<tenant>/v2.0"
  jwksUrl: "https://login.microsoftonline.com/<tenant>/discovery/v2.0/keys"
  userinfoUrl: "https://graph.microsoft.com/oidc/userinfo"
  existingSecret: "tektona-oidc"
  sessionSecret: "tektona-session"
  # Entra ID owns the accounts, so the console offers no registration.
  registrationEnabled: false
  # The sign-in form, registration, password reset and multi-factor pages need
  # the Zitadel session API. Entra ID serves all four instead.
  zitadel: {}

The audience that Tektona expects is the client-id value in tektona-oidc.

Check it

Open https://<your app host>. The console sends you straight to Microsoft. Sign in with a work account, and you land back in the console. There is no Tektona password form on this model: the provider owns the sign-in.

Exchange a provider token, for a pipeline

# Client credentials, for a pipeline.
token=$(curl -sS -X POST \
  "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token" \
  -d "client_id=<client id>" \
  -d "client_secret=<client secret>" \
  -d "scope=api://<client id>/.default" \
  -d "grant_type=client_credentials" | jq -r .access_token)

curl -sS -X POST "https://<your api host>/internal/auth/exchange" \
  -H "Authorization: Bearer ${token}"

The response carries a Tektona session token. Send it as the bearer token on every later call.

A service principal has no user behind it, so its token can come without a verified email address. The exchange then refuses to create a user for it. To permit it, name your issuer a second time:

values-control-plane.yaml
auth:
  trustedIssuer: "https://login.microsoftonline.com/<tenant>/v2.0"

The setting relaxes the check for a new user only. It never attaches a token to a user that exists, so account takeover stays blocked. The risk that you accept: a principal of your tenant can create a user row for an address that it does not own. Leave the setting empty if you do not want that.

Other providers

Okta, Keycloak and Authentik follow the same three values. Read issuer, jwks_uri and userinfo_endpoint from the discovery document of the provider, and set the audience to the client that receives the token.


Federated with Microsoft Entra ID

The full path for an enterprise. Your staff sign in with their work account, and Entra ID keeps control of the policy, the groups and the multi-factor rules.

Register Tektona in Entra ID

In the Entra admin center, open App registrations and select New registration.

  • Name: Tektona
  • Supported account types: accounts in this organizational directory only
  • Redirect URI: platform Web, and the value that Zitadel gives you. It ends in /ui/login/login/externalidp/callback.

Record the Application (client) ID and the Directory (tenant) ID from the overview page.

Then open Certificates & secrets, add a new client secret, and record the value. Entra shows it once.

Under API permissions, add the Microsoft Graph delegated permissions openid, profile, email and User.Read. Grant admin consent.

Connect Entra ID to Zitadel

In the Zitadel console, open Settings, then Identity Providers, and add a Microsoft provider.

FieldValue
Tenant typeResource owner, with your tenant ID
Client IDThe application ID from the step above
Client secretThe secret value from the step above
Scopesopenid, profile, email, User.Read

Turn on Automatic creation and Automatic update, so a person who signs in for the first time gets an account, and a name change in Entra ID reaches Tektona.

Then activate the provider in the login settings of your organization. The Tektona console reads the active list and renders a button for each one.

Register the console in Zitadel

The console is a confidential web application.

  • Redirect URI: https://<your app host>/api/auth/callback
  • Post logout URI: https://<your app host>/
  • Grant types: authorization code, with refresh token
  • Authentication method: client secret basic

Record the client ID and the client secret.

Create the secrets

The chart reads credentials from secrets. It creates none of them.

kubectl create secret generic tektona-oidc \
  --namespace tektona-system \
  --from-literal=client-id='<zitadel console client id>' \
  --from-literal=client-secret='<zitadel console client secret>' \
  --from-literal=cookie-key="$(openssl rand -hex 32)"

kubectl create secret generic tektona-session \
  --namespace tektona-system \
  --from-literal=hmac-key="$(openssl rand -hex 32)"

Set the chart values

values-control-plane.yaml
auth:
  # Zitadel is the issuer. Entra ID sits behind it.
  issuer: "https://auth.example.com"
  existingSecret: "tektona-oidc"
  sessionSecret: "tektona-session"
  # Self service registration stays off: Entra ID owns the accounts.
  registrationEnabled: false
  zitadel:
    apiUrl: "http://zitadel.zitadel.svc:8080"
    instanceHost: "auth.example.com"
    loginClientPatSecret: "zitadel-login-client-pat"

Leave auth.jwksUrl and auth.userinfoUrl empty. The chart derives the Zitadel paths from the issuer.

Check it

Open https://<your app host>. The sign-in page shows a Microsoft button. Select it, sign in with a work account, and you land in the console.

If the button is missing, the provider is not active in the Zitadel login settings of your organization.


Values reference

ValueFederatedDirect
auth.issuerZitadel URLProvider URL
auth.jwksUrlEmpty, derivedFrom the discovery document
auth.userinfoUrlEmpty, derivedFrom the discovery document
auth.existingSecretConsole client id, secret, cookie keyClient id, secret, cookie key
auth.sessionSecretHMAC key that signs the session cookieSame
auth.registrationEnabledtrue to let people registerKeep false
auth.zitadel.apiUrlZitadel API serviceLeave empty
auth.zitadel.instanceHostZitadel host nameLeave empty
auth.zitadel.loginClientPatSecretLogin client tokenLeave empty

What the direct model does not give you

The four pages that the Zitadel session API serves: the Tektona sign-in form, self service registration, password reset and the multi-factor steps. Your provider owns all four instead. Take the federated model when you need them inside Tektona.

On this page