Skip to content

Issue a Cloud Credential

A Cloud names a provider account; a CloudCredential is the vaulted secret that pays for provisioning against it. This lesson — the last of the three that build the provisioning catalog — issues a Credential under the Cloud you created in Create a Cloud, still acting as the platform operator.

The payload you hand it is the secret material the broker later spends. It is accepted inbound only and never crosses any read surface again, so a throwaway value is all this lesson needs — and because the demo Cloud is served by the floci emulator, which validates no credentials, the dummy AWS access key below is spent against floci rather than a real account.

This lesson takes about five minutes.

Before you start

This lesson builds on Create a Cloud: the demo Cloud must already exist, because a Credential is issued under a Cloud. Complete that lesson first. Beyond it you need only a running, logged-in stack from Set up your local plexsphere and jq on your $PATH.

You act as the platform operator throughout — operator@example.com, which holds the platform:plexsphere#admin authoring grant and the manage relation it received on the Cloud when it created it. See the tutorials overview for the full cast.

Recreate the shell environment:

bash
export PATH="$PWD/bin:$PATH"
export PLEXSPHERE_URL=http://localhost:8080

Step 1 — Recover the Cloud id

Sign in as the platform operator under the operator profile. The --platform flag runs the Domain-independent platform sign-in — the operator's authority is platform-wide, so no Domain is selected. Complete sign-in in the browser as operator@example.com with the password password:

bash
plexctl login --profile-name operator --platform

The credential is issued under the demo Cloud, so recover that Cloud's id from the catalog by its slug:

bash
CLOUD_ID=$(plexctl cloud list --all --profile operator --output json \
  | jq -r '.items[] | select(.slug == "demo-cloud") | .id')
echo "$CLOUD_ID"

Step 2 — Issue the demo Credential

Issue the CloudCredential under that Cloud. The payload is the secret material the broker spends; it is accepted inbound only and never crosses any read surface again, so a throwaway value is fine for the lesson:

bash
printf '{"access_key_id":"AKIAEXAMPLE","secret_access_key":"example"}' > /tmp/demo-credential.json
CREDENTIAL_ID=$(plexctl cloud credential create \
  --cloud-id "$CLOUD_ID" \
  --display-name demo-credential \
  --payload-file /tmp/demo-credential.json \
  --profile operator --output json | jq -r '.id')
echo "$CREDENTIAL_ID"

The create returns metadata only — the credential material lives in the secrets engine and never crosses this surface again. If the call returns Permission Denied, the manage grant from creating the Cloud has not reached the authorization mirror yet; wait a second and re-run it.

Step 3 — Read the Credential back

The Credential's lifecycle metadata is readable; its secret material is not. List the Cloud's credentials — cloud credential list filters each row through the observe relation on the parent Cloud, the same grant creating the Cloud gave the operator:

bash
plexctl cloud credential list --cloud-id "$CLOUD_ID" --profile operator --output json
json
{
  "items": [
    {
      "cloud_id": "019fb9c7-97ba-7d4a-8867-29e77d21c5e6",
      "created_at": "2026-06-24T18:00:36.153507Z",
      "display_name": "demo-credential",
      "expires_at": "2026-06-25T18:00:36.146475Z",
      "id": "019fb9c7-fe03-7dcf-b671-382f2b307d6f",
      "status": "active",
      "updated_at": "2026-06-24T18:00:36.153507Z",
      "version": 1
    }
  ]
}

Then fetch the one you captured by id — cloud credential get runs the same observe check before it reads:

bash
plexctl cloud credential get "$CREDENTIAL_ID" --profile operator --output json
json
{
  "cloud_id": "019fb9c7-97ba-7d4a-8867-29e77d21c5e6",
  "created_at": "2026-06-24T18:00:36.153507Z",
  "display_name": "demo-credential",
  "expires_at": "2026-06-25T18:00:36.146475Z",
  "id": "019fb9c7-fe03-7dcf-b671-382f2b307d6f",
  "status": "active",
  "updated_at": "2026-06-24T18:00:36.153507Z",
  "version": 1
}

Notice what is not there: neither read returns the access_key_id or secret_access_key you handed create. The payload is inbound-only — the read surface returns lifecycle metadata only (id, status, expiry), never the vaulted material. Both reads gate on cloud#observe on the parent Cloud; if either comes back empty or returns Permission Denied, the grant has not reached the authorization mirror yet — wait a second and re-run it.

Do this in the Console

Every step above has a browser equivalent in the Console. Open the demo Cloud's detail page from the Clouds list (under the Cloud sidebar group); its Cloud Credentials panel is the browser equivalent of cloud credential list. Issue Credential opens a dialog with a Display name and the secret Payload (sent base64-encoded, never echoed back, exactly like --payload-file); the result is metadata-only — name, version, status, expiry — never the secret you typed. Each active credential carries a Revoke action that takes a required reason and is idempotent, the browser equivalent of cloud credential revoke. Issuing and revoking are sensitive writes, so both are recorded in the session Activity stream.

What you learned

  • A CloudCredential is the secret that pays for a Cloud. It is owned by a Cloud — issuing one needs the manage relation on that Cloud, the residency pivot the issue gate authorises against.
  • The payload is inbound-only. The create returns metadata only; the secret material lives in the secrets engine and no read surface ever returns it again, so keep your own copy if you need it elsewhere.
  • The metadata is readable; the secret is not. cloud credential list and cloud credential get return lifecycle metadata — id, status, expiry — gated on observe on the parent Cloud, and confirm by omission that the payload never comes back.
  • The credential is what a Project is assigned. A Project owner later binds this Credential to a Project — by Cloud, which auto-selects it, or by naming it directly — the two-party governance Assign a Cloud Credential exercises.

Where to go next

  • Keep learning by doingAssign a Cloud Credential creates a Project and binds this Credential to it under two-party governance — the request-and-approve handshake a Project needs before it can provision.

Or pick the quadrant that matches what you need now:

  • You have a job to do — the Issue a Cloud Credential how-to covers the operator runbook, including supplying the payload from a file or stdin.
  • You want the exact contract — the plexctl cloud reference documents the cloud credential command surface and its output shape.
  • You want to understand why credentials are brokered this way — the OpenBao Credential Broker context explains how the secret material is vaulted.