Skip to content

Identity chain

The identity chain is the sequence of systems that turn “you have an Alliance CCDB account and your PI has added you to a Cloud RAP on Arbutus” 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 + RAP membership"]
    ldap["Alliance LDAP<br/>dc=computecanada,dc=ca<br/>POSIX group: &lt;rap-group-name&gt;"]
    keycloak["Keycloak<br/>OIDC broker<br/>upstream: Alliance LDAP"]
    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 -->|"PI adds you to Cloud RAP"| ldap
    ldap -->|"LDAP group membership"| 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. Your PI must explicitly add you to the Cloud RAP in CCDB.

Symptom if broken: you complete OIDC login successfully but kubectl get ns returns zero namespaces from your tenant. Remediation: ask your PI to confirm you are listed on their Cloud RAP in CCDB; if they added you recently, allow up to a few minutes for LDAP propagation.

The Alliance runs a POSIX-style LDAP directory at dc=computecanada,dc=ca. Every Cloud RAP has a corresponding LDAP POSIX group — the distinguished name pattern is dn: cn=<rap-group-name>,ou=Group,dc=computecanada,dc=ca. When your PI adds you to a Cloud RAP in CCDB, CCDB writes you into the matching LDAP group.

The LDAP layer is the authoritative source of “who belongs to what Cloud RAP”. Keycloak does not store its own copy of group membership — it reads LDAP on every authentication and issues an OIDC token reflecting whatever LDAP says at that moment. There is no intermediate cache to clear on the Kestrel side.

Symptom if broken: your OIDC token comes back with an empty or stale groups claim. Remediation: log out (kubectl oidc-login clean) and log in again; if that does not fix it, Alliance LDAP propagation may be delayed. CCDB-level issues go to accounts@tech.alliancecan.ca.

Keycloak is an OIDC broker whose upstream identity provider is Alliance LDAPnot UVic SAML, and not any institutional SSO. When you hit the Keycloak login page through kubelogin, Keycloak authenticates you against Alliance LDAP and issues an OIDC id_token whose groups claim carries the LDAP POSIX group names for every Cloud RAP you are an active member of.

RCS manages the Keycloak realm for Kestrel; you do not self-serve group membership in Keycloak. Adding or removing users is done one layer up — by the PI, in CCDB — and propagates down through LDAP into the next token Keycloak issues.

Symptom if broken: Keycloak rejects your login, or the returned id_token does not include the expected group. Remediation: see the kubelogin 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: inspect the decoded OIDC id_token and confirm the groups claim contains the expected Cloud RAP group name; if not, 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.

  • PI has not added you to the Cloud RAP. Most common failure. The kubelogin flow completes, your OIDC token validates, but kubectl get ns returns nothing. Fix: ask your PI to add you to the Cloud RAP at ccdb.alliancecan.ca. Wait for LDAP propagation (usually immediate, occasionally a few minutes).
  • Alliance LDAP propagation delay. Your PI added you, but the LDAP read happened before propagation finished. Fix: wait a few minutes, run kubectl oidc-login clean, and re-run any kubectl command to trigger a fresh login and a fresh token.
  • 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.