silicon-iam-cli
Silicon IAM from the command line. Installs a single binary, iam.
Everything the CLI can do, the silicon-iam-client crate can do —
the CLI is a shell over it and has no capability of its own. What it adds is
memory: which service, which profile, whose session, and a terminal to read a
verification code from.
First run
The session is stored under ~/.silicon-iam/ and renewed automatically when it
is close to expiring. iam logout forgets it locally; it does not end the
session on the service, so clearing one laptop does not sign you out
everywhere. Use iam session revoke for that.
Finding your way around
Commands read as noun then verb:
Everyday use
# Organizations
# Members
# Tags
# Governance
# Silicons
# Applications
app create and app rotate-webhook-secret prompt for the caller-chosen
webhook secret when --webhook-secret is omitted. IAM encrypts that value and
never generates an Application webhook secret.
Output
Text by default, aligned for reading. -o json gives the service's own JSON,
unmodified, which is what to reach for in a script:
|
Exit codes distinguish the cases worth branching on: 2 a usage mistake, 3
not signed in, 4 the service refused, 5 the service could not be reached.
Testing environments
An environment is the whole service against a separate database, starting
empty. Its UUID is safe to use in commands; its 32-character root key is not.
The CLI keeps that key in the owner-only credentials file and resolves it when
you pass --test:
CREATED=
TEST_ID=
Email and SMS delivery are suppressed and every OTP flow accepts 000000.
Webhook delivery is real, but test payloads are wrapped under test and carry
the environment key so a receiver can isolate the run. Never log that field.
Production and test credentials do not cross the boundary in either direction.
The CLI therefore keeps the production session and every environment session
in separate slots. Leaving off --test returns to production; it never reuses
the test session there.
Creation, key retrieval and key rotation automatically register the current key on this device. On a new device, authorize the mapping from a production session first:
The CLI never accepts a raw key in --test. An unknown UUID fails locally and
points to iam env key. Test-only commands likewise fail locally when
--test <environment-id> is missing.
Applications in a test environment
Create a brand-new application through the ordinary command. Its local handle must not collide with a production application in the same organization:
Or import an existing production application by canonical ID. Import creates its organization in the environment when needed, copies the base URL, webhook URL and OBO catalog, inherits the production webhook signing secret without revealing it, and returns a fresh test-only application secret:
To use a different test webhook URL, run app set-webhook inside the test
environment. Test endpoints activate immediately because an isolated plane has
no platform reviewer. For the first replacement of an imported app, pass
--webhook-secret with the caller-chosen test secret.
Rotate it explicitly with app rotate-webhook-secret; IAM never generates an
Application webhook secret.
Any test application can discover another application's base URL with its own test-only credential:
The secret is prompted for when --app-secret is omitted, keeping it out of
shell history.
Retiring one keeps it recoverable:
Signing in to an application
Naming an application prints a short-lived token it can exchange for a session:
iam silicon-login prompts for the Silicon token rather than taking it as a
flag by default, so it stays out of shell history. Without --app-id both
commands simply sign in.
End-to-end Application proof in a test environment
The complete Application protocol can be exercised without curl or SDK code.
This creates an isolated plane and two Applications, exchanges and refreshes a
login, checks it authoritatively, then mints and consumes an OBO proof. jq is
used only to carry JSON fields between iam commands:
ENVIRONMENT=
TEST_ID=
CALLER=
CALLER_SECRET=
AUDIENCE=
AUDIENCE_SECRET=
# An Application credential can discover another Application in this plane.
SLT=
TOKENS=
ACCESS=
REFRESH=
TOKENS=
ACCESS=
PROOF=
The OBO exchange reads the audience's current catalog, hashes the exact body
bytes, and signs the registered path with the caller secret. Verification
hashes the actual body again and consumes the proof once. Add
--idempotency-key and --timestamp together only when recovering the exact
same uncertain exchange.
Token exchange and refresh also accept --idempotency-key. Persist that key
before a refresh and reuse it after an uncertain outcome; retrying the same
refresh token under a new key is treated as a replay and compromises its token
family.
For normal interactive use, omit --app-secret, --slt, --refresh-token,
--token, --subject-token, or --access-proof; the CLI prompts for each so
the value does not enter shell history. They are explicit above only to make
the isolated proof reproducible.
Offline webhook verification
Save the exact body bytes and the four X-Silicon-IAM-* headers before a web
framework parses them. The CLI verifies the signature, timestamp, key version,
event ID, and event schema locally:
The signing secret is prompted for when --webhook-secret is omitted. For a
test delivery, add --test "$TEST_ID"; the CLI then also compares the wrapped
testing_key in constant time with that environment's locally stored key. A
wrapped test event without --test, a production event with --test, or a key
for a different environment is rejected. Successful output is the normalized
event and never includes the testing root key.
Profiles
One profile per service, or per identity on the same service:
Every setting can also come from the environment: SILICON_IAM_URL,
SILICON_IAM_PROFILE, SILICON_IAM_ORG, SILICON_IAM_TEST. Flags win
over environment variables, which win over stored settings.
SILICON_IAM_HOME moves the store somewhere else, which is what to use in CI so
a build never touches a developer's real credentials.
Step-up
Some actions — promoting an admin, rotating a secret, transferring ownership — need a second factor beyond the session. The service says so, and the CLI repeats it:
error: A step-up assertion is required. (step_up_required)
hint: This action needs step-up verification; re-run with --step-up.
Obtain the assertion through the step-up flow, then pass it with --step-up.
What is not here
Platform administration, the inbound provider webhooks, and the browser login screen. Those belong to the operator, to the provider, and to the browser — not to a command-line caller.
License
Licensed under the Apache License, Version 2.0. See LICENSE.
Copyright 2026 Team of Silicons.