How Ringleader signs in to your cloud

How Ringleader signs in to your cloud without a key, why only your organization can use the identity you create, and the four steps from onboarding to a running workstation.

Ringleader signs in to your cloud with a short-lived token that names your organization, and nothing else: no password or key for your account, and no identity that other Ringleader customers can also use. This is how your cloud knows a request is really from Ringleader and really for you. In Ringleader’s own vocabulary it is per-organization federation, which is the term the reference pages use.

Each time Ringleader needs to act in your cloud, it signs a short-lived token that names your organization, and your cloud checks that token against what you set up during onboarding. That setup is yours: you created it, you can read it in your cloud’s console, and you can delete it in one command to shut Ringleader out.

Why it works this way

The usual alternative, and the one Ringleader used before, is one identity owned by Ringleader that every customer’s account agrees to let in. It works, but every customer is then trusting the same thing, and a mistake anywhere affects everyone.

Instead, the token Ringleader signs for your workstations says org:<your-org-id> and nothing else, and your cloud is set up to accept exactly that. A token signed for another organization is refused by your cloud itself, not just by Ringleader.

The three values your cloud checks

Every token Ringleader signs for your organization carries three values. Ringleader works them out from which organization the workstation belongs to; nothing a user types into a workstation can change them.

ValueWhat it isWhere you configured it
Issuer (iss): who signed the token<issuer-url>/org/<org-id>GCP: issuer_uri. Azure: the credential’s Issuer. AWS: the IAM OIDC provider’s URL.
Subject (sub): which organization it speaks fororg:<org-id>GCP: attribute_condition, and the binding on the service account. Azure: the credential’s Subject identifier. AWS: the role trust’s sub condition.
Audience (aud): what it may be used forGCP: <issuer-url>/org/<org-id>/gcp. Azure: api://AzureADTokenExchange. AWS: <issuer-url>/org/<org-id>/aws.GCP: allowed_audiences. Azure: the credential’s Audience. AWS: the provider’s client-id list and the role trust’s aud condition.

To check the signature, your cloud fetches Ringleader’s public keys from:

<issuer-url>/org/<org-id>/.well-known/openid-configuration
<issuer-url>/org/<org-id>/jwks

These are public pages containing public keys. Ringleader publishes several accepted keys at once, so it can change the key it signs with without you having to redo anything.

If you know Google Cloud’s Workload Identity Federation: two different audiences

Google’s token exchange takes an audience parameter, which is the name of your workload identity provider, and that is not the same thing as the aud value inside the token. Both are checked. Mixing them up is the most common mistake when this is set up by hand; the module and the script set both correctly, so you never write either yourself.

From onboarding to a running workstation

Four steps, usually by three different people. Only the first happens in your cloud.

1. You set up the trust in your cloud

Follow the page for your cloud. Each creates an identity for Ringleader to use and tells your cloud to accept Ringleader’s tokens for your organization alone:

  • Google Cloud: a service account with three roles, and a workload identity pool that accepts the token.
  • Microsoft Azure: an Entra app with a custom role, and a federated credential that accepts the token.
  • AWS: an IAM role with a narrow policy, and an IAM OIDC provider that accepts the token.

Ringleader gives you two values up front, the issuer URL and your organization id, and you send back a handful of identifiers. All of them are public: a service-account email, a provider name, an app id, a tenant id, a subscription and a subnet.

The organization id is your organization’s uid, never its name: a name can be deleted and reused, a uid cannot.

rl org get acmecorp -o jsonpath='{.metadata.uid}'

2. An organization administrator creates the CloudAccount

The identifiers you sent back become a CloudAccount, the Ringleader object that records which identity to sign in as in your cloud, and where. There is one per cloud account, it is shared by every team in the organization, and only an organization administrator can create or change it.

apiVersion: core.ringleader.dev/v1
kind: CloudAccount
metadata:
  name: acme-gcp
spec:
  org: acme
  provider: gcp
  gcp:
    targetServiceAccount: ringleader-workstations@acme-dev.iam.gserviceaccount.com
    workloadIdentityProvider: projects/123456789/locations/global/workloadIdentityPools/ringleader/providers/oidc
rl apply -f acme-gcp-account.yaml
rl ca get

3. A namespace administrator points a CloudIdentity at it

The CloudIdentity belongs to one team’s namespace. It says how that team’s workstations are built (project, zone, machine type, subnet, labels) and which CloudAccount they use:

apiVersion: core.ringleader.dev/v1
kind: CloudIdentity
metadata:
  name: gcp
  namespace: dev
spec:
  provider: gcp
  selector:
    matchLabels:
      cloud: gcp
  cloudAccountRef: acme-gcp
  defaultProviderConfig:
    gcp:
      project: acme-dev
      zone: us-east4-c
      machineType: c4-standard-4
      subnetwork: ringleader-workstations

The namespace must belong to the same organization as the account. If it does not, the apply is refused. An account belonging to another organization and an account that does not exist give the same message, so the error cannot be used to discover other organizations’ account names.

Ringleader writes the firewall rule that admits SSH to each workstation, and every workstation that names no networkTags carries the tag the onboarding’s own SSH rule matches. If you set networkTags here, include ringleader-workstation in the list. See reaching your workstations for who can connect by default and how to narrow it.

Before anyone creates a workstation, confirm Ringleader can use the identity. This is the check that tells you the trust from step 1 actually works:

rl wait cloudidentity gcp -n dev --for Ready --timeout 2m   # waits for status.valid: true

4. A developer labels their workstation

That is all a developer does. The label the CloudIdentity looks for is the only thing a workstation needs:

apiVersion: workstations.ringleader.dev/v1
kind: Workstation
metadata:
  name: my-cloud-box
  namespace: dev
  labels:
    cloud: gcp
spec:
  requirements: [provider:gcp]
rl apply -f my-cloud-box.yaml
rl workstation wait my-cloud-box --for Ready --timeout 15m

Migrating an existing account

If your account was onboarded the old way, with a shared Ringleader identity, a CloudIdentity still using it moves over with a one-line edit: replace its spec.impersonation block with spec.cloudAccountRef, once the CloudAccount exists and your cloud has the new trust.

 spec:
   provider: gcp
-  impersonation:
-    intermediaryPrincipal: ringleader-iam@example-iam.iam.gserviceaccount.com
-    targetPrincipal: ringleader-workstations@acme-dev.iam.gserviceaccount.com
+  cloudAccountRef: acme-gcp

Three things make this safe to do gradually:

  • It is per identity. Identities that still carry impersonation keep working exactly as before; there is no coordinated all-at-once switch.
  • It is reversible. Put the impersonation block back and the identity works the old way again.
  • Both trusts can coexist. The new federated trust sits beside the existing one, so you can add it, migrate, verify, and only then remove the old one.

Migrate one identity, confirm a workstation boots through it, then move the rest.

Failure is loud, never silent

If Ringleader cannot sign in to your cloud, the workstation fails with a clear message. It never quietly falls back to some other way in, which would put a workstation back on an identity you thought you had retired:

What is wrongWhat you see
cloudAccountRef names an account your organization does not own (or that does not exist)The apply is refused.
The workstation’s namespace belongs to no organizationThe apply is refused: no token can be signed for it.
Your cloud’s trust does not match what Ringleader signsThe workstation fails to create, with the cloud’s own rejection surfaced on its status.
Ringleader itself is not set up to sign tokensThe workstation fails with an explicit “cloud federation is not configured”. Contact us.

If your cloud is the one refusing, check the three values above first, starting with the issuer, which must match exactly with no trailing slash.

See also