Skip to content

Identity chain

The identity chain is the sequence of systems that turn “you have an Alliance CCDB account and RCS has added you to your tenant’s group in Keycloak” into “the Kestrel kube-apiserver accepts your kubectl commands inside your tenant’s namespaces”. It is six layers, and the rest of this page walks each one.

flowchart TD
    ccdb["CCDB<br/>ccdb.alliancecan.ca<br/>CCI + CCRI (account + sponsorship)"]
    ldap["Alliance LDAP<br/>dc=computecanada,dc=ca<br/>user directory"]
    keycloak["Keycloak<br/>OIDC broker<br/>tenant group: &lt;rap-group-name&gt;"]
    rcs["RCS<br/>support ticket"]
    apiserver["kube-apiserver OIDC<br/>groups claim prefixed oidc:"]
    tenant["Capsule Tenant<br/>spec.owners:<br/>- kind: Group<br/>  name: oidc:&lt;rap-group-name&gt;"]
    rbac["k8s RBAC<br/>admin ClusterRole<br/>bound to &lt;rap-group-name&gt;-* namespaces"]

    ccdb -->|"account + roles"| ldap
    ldap -->|"user federation"| keycloak
    rcs -->|"adds you to the tenant group"| keycloak
    keycloak -->|"OIDC id_token with groups claim"| apiserver
    apiserver -->|"Group oidc:&lt;rap-group-name&gt; matches tenant owner"| tenant
    tenant -->|"Capsule reconciles RoleBindings per namespace"| rbac

Every layer is named by its concrete system and its concrete identifier format. If you hit a kubectl error, the layer that broke is usually obvious from the error text — the Layer-by-layer sections below tell you which layer owns which failure mode.

CCDB (ccdb.alliancecan.ca) is the Alliance’s identity and allocation registry. Every Alliance researcher has a CCDB account with a CCI (your permanent national identifier, format abc-123) and one or more CCRI roles (position + institution + sponsor, format abc-123-01). Faculty at CFI-eligible Canadian institutions get auto-approved roles; students, postdocs, research staff, and external collaborators need a PI to sponsor their role.

Your PI holds the Cloud RAP (e.g. def-profname, crg-profname-xx, or cpp-profname-xx) that backs your Kestrel tenant. CCDB’s job in the chain is the account: it is where your identity and sponsorship exist, and it is the only source Keycloak’s user store federates from. Membership in the tenant itself is granted at the Keycloak layer below.

Symptom if broken: the Keycloak login itself fails (user unknown), or RCS reports they cannot find you when asked to add you to the tenant — your account does not exist in CCDB or your sponsored role has lapsed. Remediation: register or fix the role at ccdb.alliancecan.ca; CCDB-level issues go to accounts@tech.alliancecan.ca.

The Alliance runs a POSIX-style LDAP directory at dc=computecanada,dc=ca containing every CCDB account. Keycloak’s user store federates from this directory — users are never created directly in Keycloak — so a brand-new CCDB account can take a sync cycle before Keycloak can see it. (Cloud RAPs also have POSIX groups in this directory, but Kestrel tenant membership is not currently derived from them — see the Keycloak layer below.)

Symptom if broken: you exist in CCDB but Keycloak login fails, or RCS cannot find you yet when asked to add you to the tenant group. Remediation: allow time for the new account to sync through; if it persists, contact accounts@tech.alliancecan.ca.

Keycloak is an OIDC broker whose user store is federated from Alliance LDAP — not UVic SAML, and not any institutional SSO. When you hit the Keycloak login page through kubelogin, Keycloak authenticates you and issues an OIDC id_token whose groups claim carries your Keycloak group memberships — including the tenant group named after your Cloud RAP.

The tenant group lives in Keycloak and is managed by RCS. Staff add and remove users in it on request (open a ticket); you do not self-serve group membership, and PI self-service through the Cloud RAP in CCDB is planned but not live yet. See Managing membership.

Symptom if broken: login succeeds but the returned id_token does not include the expected tenant group — usually the add-user request has not been made or completed. Remediation: confirm the ticket with your PI and RCS, then run kubectl oidc-login clean and log in again; for login-flow failures see the troubleshooting section in Install kubelogin.

The Kestrel kube-apiserver is configured to trust Keycloak as an OIDC issuer. When it validates your id_token, it re-prefixes every value in the groups claim with oidc: before handing the identity to Kubernetes authorization — so the LDAP group crg-profname-01 becomes oidc:crg-profname-01 everywhere inside the cluster. The oidc: prefix is why downstream Capsule Tenant resources list owners as oidc:<rap-group-name> rather than the bare LDAP group name.

The apiserver does not know anything about CCDB or Alliance LDAP directly. It trusts Keycloak to have already validated you, and it treats the OIDC token as the source of truth for your identity.

Symptom if broken: you authenticate successfully but kubectl returns Forbidden on everything. Remediation: run kubectl auth whoami and confirm the Groups row contains the expected oidc:<rap-group-name> — that output is exactly the identity the apiserver resolved from your token’s groups claim. If the group is missing, the problem is upstream (CCDB or LDAP), not at the apiserver.

The Capsule Tenant custom resource for your research team lists oidc:<rap-group-name> as an owner group in spec.owners — where <rap-group-name> is exactly the POSIX group name from Alliance LDAP (e.g. crg-profname-01). One Cloud RAP = one Capsule Tenant, 1:1, with the tenant name matching the Cloud RAP group name. When Capsule’s reconciler sees an admission request from that group, it treats you as a tenant owner: it allows namespace creation under your prefix, resolves your quota against the tenant’s ResourcePool, and generates the RBAC bindings that make kubectl work inside the namespaces you own.

See Tenancy model for the full Capsule Tenant shape and the namespace prefix rule.

Capsule generates RoleBindings per tenant-owned namespace that grant the admin ClusterRole — the standard Kubernetes admin role, not cluster-admin — to tenant owners inside their own namespaces. That binding is what makes kubectl get pods -n <rap-group-name>-experiments work. You are admin inside your tenant’s namespaces and have no rights anywhere else in the cluster.

  • You have not been added to the tenant group. Most common failure. The kubelogin flow completes, your OIDC token validates, but the Groups row in kubectl auth whoami shows no oidc:<rap-group-name> entry. (An empty kubectl get ns alone cannot distinguish this from a fresh tenant — Kestrel does not pre-create any namespaces for you.) Fix: have your PI confirm the add-user ticket with RCS (see Managing membership); once RCS confirms, run kubectl oidc-login clean and re-run any kubectl command for a fresh token.
  • New CCDB account not yet visible in Keycloak. Keycloak federates its users from Alliance LDAP, so a just-created account can take a sync cycle before RCS can add it to the tenant group. Fix: wait, then follow up on the ticket.
  • Expired or missing id_token cache. kubelogin caches tokens in ~/.kube/cache/oidc-login — if the cache is stale the apiserver rejects you with a 401. Fix: kubectl oidc-login clean and re-run any kubectl get command.
  • CCDB-level account issues. Your role approval is stuck, or your CCRI has lapsed. Fix: contact accounts@tech.alliancecan.ca — this is an Alliance account issue, not a Kestrel issue. Kestrel-specific support still goes through RCS; CCDB-level issues go to Alliance.
  • Tenant not yet provisioned. Your PI holds a Cloud RAP but the corresponding Kestrel tenant has not been created yet. See Requesting access.