Skip to Content
RigFabTech docs
Operate

Sign-in

People sign in to every product with your own OpenID Connect provider, such as Microsoft Entra ID, AD FS, Okta or Keycloak. This page shows how to name your provider and register each product at it.

The platform runs no sign-in service of its own. Each product is a client of your provider, with its own client ID and secret, and trusts only your provider's issuer.

Name your provider

Set your provider's issuer in the base chart's values:

signIn:
  issuer: https://login.microsoftonline.com/<TENANT_ID>/v2.0

rft check --issuer <ISSUER> reads its discovery document from where you run it. The controller checks it from the cluster, and refuses a product whose client names another issuer.

Reach the provider

The products and the controller reach the provider on HTTPS through the internet. Say where it answers when it's on your own network, or when global.rigfab.site.internetEgress is none:

global:
  rigfab:
    site:
      destinations:
        identityProvider: {cidrs: [192.168.1.10/32], ports: [443]}

Without that destination, every product that signs people in may reach any public address on port 443. Most cloud providers, Entra ID among them, answer from address ranges too wide and changeable to list. To hold the products to your provider alone, give its addresses as the destination, or route them through an egress proxy.

Trust your own CA

When the provider's certificate comes from your own CA, set global.rigfab.caBundle.configMap to a ConfigMap in rft-system and in each product's namespace with two keys:

  • bundle.pem: your CA and the public ones.
  • extra.pem: your CA alone. Node products add it to their own.

Microsoft Entra ID

With Entra ID, the base chart's controller registers each product for you through Microsoft Graph. For each product it creates:

  • an app registration with its redirect URIs and its roles as app roles
  • an enterprise application that only assigned users and groups can sign in to
  • a 180-day client secret, which it renews 30 days before it expires

You give the controller its own app registration once.

Before you begin

  • A Cloud Application Administrator role, at least, in the Microsoft Entra admin center.
  • A Privileged Role Administrator or Global Administrator to grant admin consent.

Register the controller

Go to App registrations > New registration.

  • Name it, for example, RigFabTech platform (rft.example.com).
  • Choose Accounts in this organizational directory only.
  • Give no redirect URI.

Add a credential

Under Certificates & secrets, upload a certificate (recommended; RSA, 2048 bits or more) or add a client secret. Note when it expires.

Add the Graph permission

Under API permissions > Add a permission > Microsoft Graph > Application permissions:

  • Add Application.ReadWrite.OwnedBy.
  • Remove User.Read.

Application.ReadWrite.OwnedBy lets the controller create app registrations and change only those it created. It can still list the other applications in your tenant, but not change them.

A Privileged Role Administrator or Global Administrator selects Grant admin consent for <tenant>.

With the Azure CLI instead:

az ad app permission add --id <CLIENT_ID> --api 00000003-0000-0000-c000-000000000000 \
  --api-permissions 18a4783c-866b-4cc7-a460-3d5e5662c884=Role
az ad app permission admin-consent --id <CLIENT_ID>

Store the credential

Keep the credential in Secret rft-entra in rft-system, either as tls.crt and tls.key (PEM) or as client-secret:

kubectl --namespace rft-system create secret generic rft-entra --from-file=tls.crt=controller.crt --from-file=tls.key=controller.key

Set the values

Set the tenant and client in the base chart's values. The issuer follows from the tenant.

signIn:
  entra:
    tenantId: <TENANT_ID>
    clientId: <CLIENT_ID>

Assign people and groups

Each product appears in Enterprise applications as <product> (rft-<domain>). Assign people or groups to its roles there, under Users and groups.

  • A person with no assignment can't sign in. signIn.entra.assignmentRequired: false lets everyone in the tenant sign in without a role.
  • Assigning groups, rather than people, needs Microsoft Entra ID P1 or P2.

Let the controller assign groups

To have the controller assign groups too, map <product>.<role> to group object IDs:

signIn:
  entra:
    roleGroups:
      pattern-shop-tracker.admin: [<GROUP_OBJECT_ID>]

The controller only adds assignments. One you remove from roleGroups stays until you remove it in the portal.

This needs two more application permissions:

  • AppRoleAssignment.ReadWrite.All (06b708a9-e830-4db3-a914-8e69da51d44f)
  • Application.Read.All (9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30)

AppRoleAssignment.ReadWrite.All lets the holder grant any application permission in your tenant. It makes the controller's credential as powerful as a Global Administrator's. Assigning groups by hand in the portal needs neither permission.

How the controller manages registrations

  • It owns them. Every 10 minutes it sets their redirect URIs, roles, claims and tags again. Change them through the chart, not in the portal.
  • It renews client secrets. When it renews a product's client secret, it restarts the product's pods onto the new one.
  • It deletes them. Uninstalling a product deletes its registration. Entra ID keeps it in Deleted applications for 30 days. A product you later give signIn.existingSecret has its registration deleted too.
  • No back-channel logout. Entra ID has no OpenID Connect back-channel logout, so a product's backchannelLogoutURI isn't registered there. The products' short sessions bound how long a person you disable keeps one.

Each cluster needs its own signIn.entra.namePrefix, rft-<domain> by default. Two clusters with one prefix would share and break each other's registrations.

Uninstall the products before rft-base, and keep rft-entra until they're gone, so the controller can delete their registrations. Without it, a product's PlatformApp keeps its finalizer. See Uninstall.

Products that call Microsoft Graph

Products that sign in to Microsoft Entra ID themselves, such as to call Microsoft Graph, read the tenant from the same site.yaml. They use signIn.entra.tenantId, or the tenant in signIn.issuer when it is your Entra login host's https://<LOGIN_HOST>/<TENANT_ID>/v2.0, such as https://login.microsoftonline.com/<TENANT_ID>/v2.0. Each product's settings page says whether it reads it.

Rotate the controller's credential

Rotate the controller's own certificate or secret before it expires:

  1. Add the new one to its app registration.
  2. Replace rft-entra.
  3. Remove the old one.

The controller reads the Secret on every pass.

Another provider

Register each product at your provider yourself.

Install the product

Its PlatformApp lists what to register:

kubectl --namespace rft-app-<PRODUCT> get platformapp <PRODUCT> --output jsonpath='{.status.signIn}'

It prints:

  • redirectURIs and postLogoutURIs, such as https://<PRODUCT>.<domain>/auth/callback
  • backchannelLogoutURI, when the product takes back-channel logout
  • its roles

Register a client

At your provider, register a confidential web client for the product:

  • with those URIs
  • with the authorization code flow
  • with the openid, profile and email scopes

Put the product's roles from its status, such as admin, in the ID token's roles claim for the people who hold them.

Store the client

Keep the client in a Secret in the product's namespace:

kubectl --namespace rft-app-<PRODUCT> create secret generic sign-in \
  --from-literal=issuer=<ISSUER> --from-literal=client-id=<CLIENT_ID> --from-file=client-secret=client-secret.txt

Name the Secret

Name it in the product's values as signIn.existingSecret.

  • With one values file for every product, as rft config writes, signIn.existingSecret: sign-in names a Secret sign-in in each product's namespace.
  • A product with signIn.existingSecret uses that client even when the controller registers the others at Entra ID.

The controller copies the client into <PRODUCT>-oidc, which the product reads, and the PlatformApp turns ready.

Rotate the client secret

Change it at your provider and in the Secret. Within a minute, the controller copies it and restarts the product's pods onto it.

Sessions

Products built on the platform's identity libraries:

  • keep a session at most 8 hours
  • end it after 30 minutes without use
  • check the platform's directory every 5 minutes; each check may use an answer up to a minute old

So disabling someone at your provider, or removing their role, reaches them within about 6 minutes once your provider provisions the change. See User provisioning.

Products that support it also end sessions at once when your provider sends an OpenID Connect back-channel logout to the URL in their PlatformApp's status.signIn.backchannelLogoutURI. Each product's documentation says what it does.

Emergency access

The products have no local accounts. Keep two emergency-access accounts in your provider, as Microsoft recommends for Entra ID, and give them the roles that administer each product.

Next steps