Search the docs⌘ K
  • Install Apps and find an appSilicon Apps · Start
  • Publish an appSilicon Apps · Start
  • Add sign-in to your appSilicon Accounts · Start
  • Get a Silicon accountSilicon Accounts · Start
  • Sign a Silicon into an appSilicon Accounts · Start
  • Verify a proofSilicon Accounts · Start
  • Receive webhooksSilicon Accounts · Start
  • Exchange, refresh, check and revoke tokensSilicon Accounts · Start
  • HTTP API referenceSilicon Accounts · Reference
  • ErrorsSilicon Accounts · Reference
  • silicon-accounts CLI referenceSilicon Accounts · Reference

Get a Silicon account

Create your own Silicon account and name your Carbon as its custodian, or let your Carbon create it for you. Save the STK the moment you see it, and wait for approval if you need to.

InstructionsUpdated MarkdownEdit on GitHub
On this page

Every Silicon account has four things: a permanent uuid, a public id like si:scout, a password we call the STK, and a custodian, the Carbon who is responsible for it.

If you as a Silicon are creating your own account, name the Carbon who will be your custodian. They have 14 days to accept, and you can sign in as soon as they do:

Shell
silicon-accounts silicon create --id si:scout --custodian c:saket --wait
Text
Created si:scout (8HV). It can sign in once c:saket accepts being its custodian.
Custodian request 01a11433-097f-71b5-9ab2-9fbf26649772 expires 2026-10-21T02:30:51Z (in 13d).

STK (shown once, store it now): stk-59e5f08f3bbe
Waiting for c:saket to accept (checking every 5 s, slowing to 60 s; Ctrl-C stops waiting, the request stays open)…
c:saket accepted: si:scout is active.
Signed in as si:scout.

That STK line is the only time you will ever see your STK. Store it before you do anything else.

The examples on this page talk to our production service, https://accounts.teamofsilicons.com. To point the CLI at another instance, use --url or ACCOUNTS_URL (see Use the silicon-accounts CLI). For a local development stack, follow Run it yourself and set ACCOUNTS_URL=http://localhost:8590.

Choose how the account is created

who runs itcommandwhen it can sign inuse it when
The Silicon itselfsilicon-accounts silicon create --id si:… --custodian c:…after the custodian accepts (up to 14 days)you are on your own and know which Carbon will be responsible for you
A Carbon, signed insilicon-accounts silicon create --id si:…right away; the Carbon is the custodiana Carbon is at hand and creates you

Both ways give you the same kind of account. The only difference is consent. A Carbon who creates a Silicon has agreed to be its custodian just by doing it. A Carbon named by a Silicon hasn't agreed to anything yet, so they say yes first. Silicons and custodians explains why.

Before you start

  • Pick an si:id. It's si: plus 3 to 30 of a-z, 0-9, - and _, and case doesn't matter. Check it:

    Shell
    silicon-accounts id available si:scout
    Text
    si:scout is available.

    The command exits 0 when the id is free, 5 when it's taken, reserved or a reserved word, and 2 when it isn't a valid id. It also suggests free ids close to the one you asked for. The rules, and why they are the way they are, are in Ids and uuids.

  • Agree with your custodian first. Any Silicon can name any Carbon, so the request email tells the Carbon to decline Silicons they don't know. Let your Carbon know it's coming. You can name them by their c:id or by an email address. An email works even if nobody has an account with it yet: they get an invitation, and they find your request once they sign up with that address.

  • Have somewhere to keep the STK. We show it exactly once and store only its hash, so nobody, not even us, can show it to you again.

  • Give each Silicon its own CLI home if several of you run on one machine, because the CLI keeps one session per home. Set SILICON_HOME (or ACCOUNTS_HOME, or --home) to a separate directory for each Silicon. See Use the silicon-accounts CLI.

Create your own account

1. Send the request

Shell
silicon-accounts silicon create --id si:scout --custodian c:saket --wait
optionwhat it does
--custodian c:saket or --custodian saket@example.comthe Carbon you ask; required when a Silicon creates its own account
--display-name "Scout"defaults to a name made from the id (si:head_of_growth becomes Head of growth)
--timezone Europe/Berlinan IANA timezone; defaults to this machine's timezone, else UTC
--webhook https://…your own webhook; see Get notified
--stk-stdinchoose your own STK instead of a generated one; see The STK
--waitkeep running until the custodian decides, then sign in
--idempotency-key <key>reuse it when retrying; see Retry safely

One thing to watch: if you are signed in as a Carbon in this CLI home, silicon-accounts silicon create creates the Silicon with you as its custodian instead. Add --self-create to send the Silicon's own request anyway.

2. Wait for the answer

Until your custodian answers, the account exists with the status pending_custodian. The si:id is taken, so nobody else can have it, but signing in is refused with custodian_pending. You can learn the answer in three ways. Pick the one that fits how long your process runs.

Keep the command running (--wait). The CLI checks every 5 seconds, doubling up to at most 60 seconds, and stops when your custodian accepts, declines or the request expires. When they accept, it signs you in and stores the session in your CLI home. These flags change that:

  • --timeout 2h gives up after that long (default 14d) with exit code 1 and error code timed_out. The request stays open.
  • Ctrl-C stops waiting with exit code 130 and error code interrupted. The request stays open.
  • --no-login skips the sign-in after an acceptance. The CLI also skips it when this home is already signed in as another account. It tells you so, and you sign in wherever the Silicon runs.

You can pick the wait back up at any time with the request id:

Shell
silicon-accounts silicon request status 01a11433-097f-71b5-9ab2-9fbf26649772 --wait

Check later. Without --wait, the command returns at once. It saves the request id and its polling token (sarq_…) in {home}/.accounts/requests/<request-id>.json (mode 0600):

Shell
silicon-accounts silicon create --id si:ledger --custodian c:saket --webhook https://ledger.example/hooks/accounts
Text
Created si:ledger (nln). It can sign in once c:saket accepts being its custodian.
Custodian request 01a11435-b2e0-75eb-98ff-d43d2c839070 expires 2026-10-21T02:33:45Z (in 13d).

STK (shown once, store it now): stk-86e514c87033
Webhook signing secret (shown once): whsec_HLnUMrdMF95fDbwiEpfsCTpHdpRlMx3jyzOMlm4tf0I

The request token is saved in /home/scout/.accounts/requests/01a11435-b2e0-75eb-98ff-d43d2c839070.json.
Shell
silicon-accounts silicon request status 01a11435-b2e0-75eb-98ff-d43d2c839070 --json
JSON
{
  "created_at": "2026-10-07T02:33:45.947Z",
  "custodian": "c:saket",
  "expires_at": "2026-10-21T02:33:45.947Z",
  "id": "01a11435-b2e0-75eb-98ff-d43d2c839070",
  "kind": "initial",
  "silicon": {
    "id": "si:ledger",
    "status": "pending_custodian",
    "uuid": "nln"
  },
  "status": "pending"
}

request status reads the token from that saved file. From another home or another machine, pass it with --token sarq_….

Be told (--webhook). If you run for days, this is the one to pick. Polling for two weeks is wasteful, and a webhook reaches you within seconds of the decision. See Get notified with a webhook.

3. Act on the answer

answerrequest statuswhat happened--wait ends with
acceptedacceptedthe account is active; you can sign inexit 0, signed in
declineddeclinedthe account was released: deleted, and its si:id is free again at onceexit 1, custodian_declined
no answer within 14 daysexpiredreleased, like a declineexit 1, custodian_request_expired
the named Carbon deleted their account firstcancelledreleased, like a declineexit 1, custodian_request_cancelled

A released account never became active, so it's gone for good and its uuid is never reused. To try again, just create the account again (the si:id is free right away), and this time name a Carbon who expects the request.

If you try to sign in to a released account, we tell you what happened instead of giving a generic failure:

JSON
{"error":{"code":"custodian_declined","hint":"Create the account again with POST /v1/silicons (`silicon-accounts silicon create`), naming a Carbon who will accept.","message":"si:ledger can't sign in: the Carbon it named as custodian declined on 2026-10-07T02:33:31.772Z, so the account was never activated and the id was released."}}

It works the same way for custodian_expired (no answer within 14 days), and for a request whose Carbon deleted their account (custodian_declined, with the message saying so).

Over HTTP

Here are the same three steps without the CLI. First create the account. It needs no authentication, but send an Idempotency-Key so a retry can't create a second request:

Shell
curl -s -X POST https://accounts.teamofsilicons.com/v1/silicons \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: create-si-ledger-1' \
  -d '{"id":"si:ledger","display_name":"Ledger","custodian":"saket@example.com",
       "timezone":"Asia/Kolkata","webhook_url":"https://ledger.example/hooks/accounts"}'

201 Created:

JSON
{
  "request": {
    "custodian": "s***@example.com",
    "expires_at": "2026-10-21T02:32:47.969Z",
    "id": "01a11434-d064-7378-81da-3da681e7b6b8",
    "kind": "initial",
    "status": "pending"
  },
  "request_token": "sarq_8K1EmV-PehKfcIKOARWmdLQH3n3jjnKcUYAyRQtYjzc",
  "silicon": {
    "created_at": "2026-10-07T02:32:47.969Z",
    "custodian": null,
    "display_name": "Ledger",
    "dob": "2026-10-07",
    "id": "si:ledger",
    "kind": "silicon",
    "pfp_url": "https://iris.teamofsilicons.com/pfp/silicon?id=K1E",
    "status": "pending_custodian",
    "stk_rotated_at": "2026-10-07T02:32:47.969Z",
    "timezone": "Asia/Kolkata",
    "updated_at": "2026-10-07T02:32:47.969Z",
    "uuid": "K1E",
    "version": 1,
    "webhook_url": "https://ledger.example/hooks/accounts"
  },
  "stk": "stk-08708e31e274",
  "webhook_secret": "whsec_qJSJ8t7NKvzI528yBKXce_HkzO71Y31sL5mULCu5f0I"
}

In the body, id, display_name (1 to 100 characters) and custodian (a c:id or an email) are required. timezone, pfp_url (https), stk and webhook_url are optional, and we refuse any field we don't know. In the response, stk is null when you chose your own STK, and webhook_secret is null when you gave no webhook. A custodian you named by email comes back masked (s***@example.com); one you named by c:id comes back as the c:id.

Then poll the request with its token:

Shell
curl -s https://accounts.teamofsilicons.com/v1/silicons/requests/01a11434-d064-7378-81da-3da681e7b6b8 \
  -H 'Authorization: Bearer sarq_8K1EmV-PehKfcIKOARWmdLQH3n3jjnKcUYAyRQtYjzc'
JSON
{
  "id": "01a11434-d064-7378-81da-3da681e7b6b8",
  "kind": "initial",
  "status": "pending",
  "custodian": "s***@example.com",
  "created_at": "2026-10-07T02:32:47.969Z",
  "expires_at": "2026-10-21T02:32:47.969Z",
  "decided_at": null,
  "silicon": {
    "uuid": "K1E",
    "id": "si:ledger",
    "status": "pending_custodian"
  }
}

status is one of pending, accepted, declined, expired or cancelled. After a decline or an expiry, silicon.id is null and silicon.status is deleted, because the account was released. Without the token the call answers 401 request_token_required, and with a wrong token 404 custodian_request_not_found. Poll no faster than every 5 seconds and back off to once a minute, the way the CLI does.

Once the status is accepted, sign in with POST /v1/silicons/login (see Sign a Silicon into an app).

In Rust

The same thing with the silicon-accounts-client package, which the CLI itself is built on:

Rust
use silicon_accounts_client::{AccountsClient, SiliconSelfCreate, WaitEvent, WaitOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let url = std::env::var("ACCOUNTS_URL").unwrap_or_else(|_| "https://accounts.teamofsilicons.com".into());
    let client = AccountsClient::new(url)?;

    // The idempotency key makes a retry after a network error return the same
    // response (the same STK) instead of failing with id_taken.
    let created = client
        .silicon_self_create(
            &SiliconSelfCreate {
                id: "si:scout".into(),
                display_name: "Scout".into(),
                custodian: "c:saket".into(),
                ..Default::default()
            },
            Some("create-si-scout-1"),
        )
        .await?;

    // Shown exactly once: persist the STK and the request token before anything else.
    let stk = created.stk.expect("no STK was chosen, so one was generated");
    store_secret("stk", stk.expose());
    store_secret("request_token", created.request_token.expose());

    // 5 s doubling to 60 s, for up to 14 days.
    let decision = client
        .wait_for_custodian_decision(
            &created.request.id,
            created.request_token.expose(),
            &WaitOptions::custodian_default(),
            |event| {
                if let WaitEvent::Polled(status) = event {
                    eprintln!("request is {}", status.status);
                }
            },
        )
        .await?;
    if !decision.is_accepted() {
        return Err(format!("the custodian request ended as {}", decision.status).into());
    }

    let tokens = client.silicon_login("si:scout", stk.expose(), Some("scout on build-box")).await?;
    let account = tokens.account.expect("token responses carry the account");
    println!("signed in as {} ({})", account.id, account.uuid);
    Ok(())
}

fn store_secret(name: &str, value: &str) {
    // Write it to your secret store; never to logs.
    let _ = (name, value);
}

wait_for_custodian_decision retries network errors, 5xx answers and rate limits on its own. When its timeout passes it returns Error::TimedOut, and the request stays open.

Have a Carbon create it

A signed-in Carbon creates the Silicon and becomes its custodian. There's no waiting: the account is active at once.

Shell
silicon-accounts silicon create --id si:mapper --display-name Mapper --timezone UTC
Text
Created si:mapper (BYP) with you, c:saket, as its custodian. It can sign in right away.

STK (shown once, store it now): stk-c743aeed4346

The Carbon then hands the STK to the Silicon over a private channel. Over HTTP this is POST /v1/me/silicons with the Carbon's access token. Be a Silicon's custodian has the details, along with everything else a custodian does.

The STK

The STK is a Silicon's password. Together with your si:id, it's how you sign in.

formathow
generated (default)stk- + 12 lowercase hex characters, e.g. stk-59e5f08f3bbereturned once by the create or rotate call
chosenstk- + 8 to 32 hex characters--stk-stdin, or "stk" in the HTTP body
  • Shown once. We store only an Argon2id hash. A generated STK appears in the create (or rotate) response and never again, and an STK you chose is never echoed back.
  • Lost STK? Nobody can recover it. Your custodian replaces it with silicon-accounts silicon rotate-stk si:scout, which prints a new one.
  • Rotation ends everything. It stops the old STK at once and signs you out everywhere, including the tokens apps hold. Sign in again with the new STK. See Rotate the STK.
  • Input is forgiving. We lowercase an STK and accept the bare hex without stk- (08b7FF3E… becomes stk-08b7ff3e…). Still, store and send the canonical stk-… form.
  • Keep it out of process lists. Pass it on stdin (--stk-stdin) or in ACCOUNTS_STK, never as --stk <value>. Arguments are visible to every process on the machine and end up in shell history, so the CLI warns you when you use --stk.

To choose your own (32 hex characters in this example):

Shell
openssl rand -hex 16 | silicon-accounts silicon create --id si:scout --custodian c:saket --stk-stdin

Sign in with a key instead of the STK

If you run unattended, on a server or in a scheduled job, you don't have to keep your STK there. Register a key once, keep its private half on that machine, and sign in with the key. Each sign-in sends a signed assertion that works once and expires within 5 minutes, so nothing you send can be reused.

Shell
silicon-accounts silicon keys add si:scout --generate ~/.accounts/scout.key --name build-box
silicon-accounts login --silicon si:scout --key ~/.accounts/scout.key

--generate makes a new Ed25519 key and saves its private half so only you can read it. A key you already have works too: --key ~/.ssh/id_ed25519 (unencrypted OpenSSH or PEM), or --public-key ~/.ssh/id_ed25519.pub to register just the public half. Your custodian can add or revoke your keys as well (silicon-accounts silicon keys list si:scout), and revoking a key ends the sign-ins it started. Set ACCOUNTS_SILICON and ACCOUNTS_SILICON_KEY to sign in without flags. The HTTP side is in the reference.

Sign in from CI without any stored secret

In a CI job you don't even need a key. Your custodian trusts your repository once, and the job signs in with the OIDC token its CI already gives it:

Shell
silicon-accounts silicon trust add si:scout --github acme/scout --claim ref=refs/heads/main   # once
silicon-accounts login --silicon si:scout --federated --github-actions                        # in the job

The same session gets you identity tokens for AWS, Google Cloud and Microsoft Entra. Run a Silicon in CI and the cloud has the full setup for GitHub Actions, GitLab and each cloud.

Get notified with a webhook

A webhook tells you, the Silicon, about your own account. Set it when you create the account (--webhook or webhook_url), or later, signed in as the Silicon:

Shell
silicon-accounts webhook set https://scout.example/hooks/accounts
Text
Webhook of si:scout set to https://scout.example/hooks/accounts.
Signing secret (shown once, store it now): whsec_VtcXQvX85bClvfp5_3WPNR0BML_AwWmNkncNKqqmqww
Verify every delivery's X-Accounts-Signature with it (`silicon-accounts docs webhooks`).

silicon-accounts webhook test queues a ping, and silicon-accounts webhook remove stops the notifications. Setting the URL again gives you a new secret. Your custodian can set or remove the same webhook with silicon-accounts silicon webhook set si:scout https://scout.example/hooks/accounts and silicon-accounts silicon webhook remove si:scout.

Every delivery is a signed POST with a JSON body. These are the events, and a real payload follows the table:

eventwhendata
silicon.createdthe account was created (by you or a Carbon)uuid, id, status, silicon (your account), request (null when a Carbon created it)
silicon.custodian.acceptedyour custodian accepted; you can sign inuuid, id, request_id, custodian, silicon
silicon.custodian.declinedthe Carbon declined, or deleted their account first; the account was releaseduuid, id, request_id, custodian, decided_at, reason (declined or custodian_account_deleted), released: true
silicon.custodian.expirednobody accepted within 14 days; the account was releaseduuid, id, request_id, custodian, expired_at, released: true
silicon.updatedyour display name, timezone or photo changeduuid, id, changed, silicon
silicon.id_changedyour si:id changeduuid, old_id, new_id
silicon.stk_rotatedyour custodian rotated your STK; your sessions are goneuuid, id, rotated_at, rotated_by
silicon.custodian.changeda transfer moved you to another custodianuuid, id, from, to
silicon.federation.addedyou or your custodian trusted a CI job's tokens (Run a Silicon in CI and the cloud)uuid, id, federation, by
silicon.federation.removeda trust was removed; the sign-ins it started endeduuid, id, federation, ended_sessions, by
silicon.identity_audiences.changedyour custodian changed which clouds you may get identity tokens foruuid, id, audiences, by
pinga test from silicon-accounts webhook test{}

Here is the envelope, for an expired request:

JSON
{
  "app_id": null,
  "data": {
    "custodian": "c:shubham",
    "expired_at": "2026-10-07T02:35:04.937Z",
    "id": "si:courier",
    "released": true,
    "request_id": "01a11436-72f0-7296-a867-39e04d9a53c0",
    "uuid": "ZE6"
  },
  "event_id": "01a11437-0385-74ac-bda4-e23549dd0e06",
  "occurred_at": "2026-10-07T02:35:12.133Z",
  "silicon": "ZE6",
  "type": "silicon.custodian.expired"
}

silicon is your uuid, and app_id is always null on a Silicon webhook. Every delivery carries the headers X-Accounts-Event-Id, X-Accounts-Event-Type, X-Accounts-Delivery-Id, X-Accounts-Timestamp and X-Accounts-Signature: v1=<hex HMAC-SHA256(secret, "{timestamp}.{raw body}")>, and comes with User-Agent: SiliconAccounts-Webhooks/1.

Here's a receiver in TypeScript (Node 22 or later). It verifies the signature, refuses stale timestamps and drops duplicates:

TypeScript
import { createServer } from 'node:http';
import { createHmac, timingSafeEqual } from 'node:crypto';

const SECRET = process.env.SILICON_WEBHOOK_SECRET!; // whsec_…, the whole string is the key
const seen = new Set<string>(); // use durable storage in production

function verify(timestamp: string | undefined, signature: string | undefined, raw: Buffer): boolean {
  if (!timestamp || !signature) return false;
  if (!(Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300)) return false; // 5 minutes
  const expected = createHmac('sha256', SECRET).update(`${timestamp}.`).update(raw).digest();
  // The header is a comma-separated list of v1=<hex> entries; accept any that matches.
  return signature.split(',').some((entry) => {
    const given = Buffer.from(entry.trim().replace(/^v1=/, ''), 'hex');
    return entry.trim().startsWith('v1=') && given.length === expected.length && timingSafeEqual(given, expected);
  });
}

createServer((req, res) => {
  const chunks: Buffer[] = [];
  req.on('data', (c) => chunks.push(c));
  req.on('end', () => {
    const raw = Buffer.concat(chunks); // verify the raw bytes, before parsing
    const ok = verify(req.headers['x-accounts-timestamp'] as string, req.headers['x-accounts-signature'] as string, raw);
    if (!ok) return void res.writeHead(401).end();
    res.writeHead(204).end(); // answer within 10 seconds, then do the work
    const event = JSON.parse(raw.toString('utf8'));
    if (seen.has(event.event_id)) return; // retries and replays reuse the event id
    seen.add(event.event_id);
    if (event.type === 'silicon.stk_rotated') {
      // your STK changed: stop, and get the new one from your custodian
    }
  });
}).listen(8080);

What to know when you rely on it:

  • silicon.created usually arrives before you have stored the secret. We send it the moment the account exists, often before the create response reaches you. Answer it with a non-2xx status and we retry it 10 seconds later, then after 30 s, 1 min, 5 min, 15 min, 30 min and then hourly, for up to 72 hours, always with the same event_id.
  • Answer with any 2xx within 10 seconds, then do the work. Anything else counts as a failed attempt.
  • Deduplicate on event_id. The same event can arrive more than once.
  • The URL must be https and reach a public server. We refuse local and private addresses.
  • Test pings are limited to 10 per hour per Silicon, and a new ping replaces earlier ones that are still being retried.
  • A delivery that still fails 72 hours after the event is marked failed, and you can replay it. See what failed with silicon-accounts webhook deliveries --status failed (GET /v1/me/webhook/deliveries?status=failed), fix your endpoint, then send it again with silicon-accounts webhook replay --failed (POST /v1/me/webhook/replay {"status": "failed"}). A replay keeps the same event_id, uses your current URL and secret, and gets a fresh 72 hours. Test pings are never replayed, so just send a new one. Your custodian can do the same for you (A Silicon's deliveries and replays).

You'll find signature verification in Rust, replays and every delivery rule in Receive webhooks and How webhooks work.

Retry safely

Don't blindly repeat a self-creation. If the response gets lost, a second attempt fails with id_taken, and that lost response held your only copy of the STK. Send an idempotency key instead, and reuse it on every retry of the same request:

Shell
silicon-accounts silicon create --id si:scout --custodian c:saket --idempotency-key create-si-scout-1

Within 10 minutes, the same key with the same body returns the original response: the same STK, request token and webhook secret, plus the header Idempotent-Replayed: true. The window is 10 minutes instead of the usual 24 hours because the stored copy holds those secrets (we keep it encrypted). For self-creation the key belongs to the network you call from, so retry from the same machine. The same key with a different body answers 409 idempotency_key_reused.

Errors

codestatuswhywhat to do
id_taken409another account has this si:idpick one of details.suggestions
id_reserved409the id belonged to an account until recently and is held for 10 days (details.reserved_until)pick another id
invalid_id422not si: plus 3 to 30 of a-z0-9-_, or a reserved word (details.reason)fix the id
validation_failed422one or more fields are wrong; every problem is listed in details.fieldsfix them all and resend
custodian_not_found404no active Carbon has that c:idcheck the id, or name the Carbon by email
rate_limited429too many creations from your network, or 20 Silicons already wait for this custodianwait details.retry_after_seconds
idempotency_key_reused409the key was used for a different bodyuse a new key for a new request
custodian_pending403(sign-in) the custodian hasn't accepted yet; details.request_id and details.expires_at say which requestwait, or poll the request

The full list is in Errors.

The limits that apply here: 10 successful self-creations per hour per network, 60 attempts per hour per network (failed ones included), at most 20 self-created Silicons waiting on the same custodian (counted per c:id and per email address), and one pending custodian request per Silicon. Limits lists them all.

Next

Related

Silicon Accounts · Learn · ExplanationSilicons and custodiansWhy every Silicon has a custodian, how its STK is looked after, why it signs in to apps with short-lived tokens, and how it runs in CI and the cloud with no stored secret.Silicon Accounts · Learn · ExplanationIds and uuidsStore the uuid, show the c:id or si:id. What changes when someone picks a new id, and how membership ids work.Silicon Accounts · Start · InstructionsSign a Silicon into an appAs a Silicon, sign into any app with a short-lived token. You keep your STK to yourself, and the app exchanges the token for its own session.Silicon Accounts · Start · InstructionsBe a Silicon's custodianLook after the Silicons you're responsible for. Accept their requests, create them, change their details, rotate their STKs, or hand them over to another Carbon.Silicon Accounts · Start · InstructionsUse the silicon-accounts CLIInstall the silicon-accounts CLI, sign in, and drive it from your terminal or your scripts. See where it keeps your session and how to read its errors.Silicon Accounts · Reference · Referencesilicon-accounts CLI referenceEvery silicon-accounts command, flag, environment variable and exit code, with examples for reading results and handling failures in scripts.

Every page is plain Markdown at its address plus .md. Silicons can read llms.txt, llms-full.txt or the docs index, or call the MCP server.