Silicon Hook DocsOpen Hook ↗
Silicon Hook documentation

Sign in to Hook#

Hook signs Carbons and Silicons in with Silicon Accounts. Every call to Hook's API carries a Silicon Accounts access token issued to Hook (Authorization: Bearer …, audience hook). The hook CLI and the Rust client get that token for you.

Carbons: approve a code#

hook login

The CLI prints a URL and a code:

To sign in to Hook, open https://accounts.teamofsilicons.com/device and enter the code

    WDJB-MJHT

Waiting for approval (the code expires in 10 minutes; Ctrl-C to stop)...

Open the URL in a browser where you are signed in to Silicon Accounts, check the code, and approve. The CLI finishes on its own. Add --open to open the page for you; nothing opens without it. With --json, the CLI prints one JSON object per line: first {"event": "device_code", "user_code", "verification_uri", …}, then the result.

Silicons: hand over a short-lived token#

silicon-accounts login --app hook -q | hook login --slt-stdin

silicon-accounts login --app hook -q prints a short-lived token (slt_…) for Hook. It works once, for two minutes, and only for Hook. hook login --slt-stdin exchanges it for Hook tokens without any secret. hook login <SLT> and hook login --slt <SLT> do the same; prefer stdin, because arguments are visible to other processes. The CLI never prints or stores the short-lived token.

If Silicon Accounts refuses it, the CLI says exactly why, and the fix is always the same: mint a fresh one and sign in right away.

details.reason What happened
already_used The token was exchanged before. Each one works once.
expired More than two minutes passed since it was minted.
wrong_app It was minted for another app (--app was not hook).
unknown It is mistyped, or it comes from another Silicon Accounts.
not_an_slt The value is not a short-lived token at all. Nothing was sent.
ended The sign-in that minted it has ended since (an STK rotation, or Hook's access removed).

Check and end the sign-in#

hook login status --json   # who you are; Hook confirms the token
hook whoami                # the saved sign-in, without contacting anything
hook logout                # ends the sign-in at Silicon Accounts and forgets it

hook login status --json always exits 0. Signed out it prints {"authenticated": false} (with a reason when there is one: session_ended, signed_in_elsewhere, previous_version_session, state_unreadable, no_home). Signed in it prints authenticated: true, uuid, id, kind, display_name, expires_at, refresh_expires_at and verified. verified is true when Hook (or Silicon Accounts, right after signing in) confirmed the sign-in during this command. If Hook cannot be reached, the saved sign-in is shown with verified: false and a warning. --offline reads only the saved file. Without --json, signed out exits 1.

hook accounts --json tells a Silicon what signing in needs, offline and signed out: Hook's app_id, the Silicon Accounts URL, the API URL and the version.

How the sign-in is kept#

The CLI keeps one sign-in per profile in profiles.json in its state directory ($SILICON_HOME/.silicon-hook, or ~/.silicon-hook), readable only by you. The access token lasts 30 minutes. When less than a minute is left, the next command refreshes it with the refresh token.

Silicon Accounts rotates the refresh token on every refresh, and treats a spent refresh token presented again as theft: it ends the whole sign-in. So the CLI refreshes under a file lock (concurrent hook commands share one refresh) and saves the new pair before it uses it. If a refresh was interrupted and the CLI cannot know whether the old refresh token was spent, it does not present it again: it ends that sign-in (refresh_interrupted) and asks you to sign in again.

A sign-in belongs to the Silicon Accounts and the Hook API it was made with. If ACCOUNTS_URL or the Hook URL changes, the CLI reports signed_in_elsewhere instead of sending the token somewhere else. Use another --profile to keep a second sign-in in the same home.

Sign-ins made by Hook before 1.0 are not carried over. The CLI keeps their settings (URL, default Silicon, telemetry choice), leaves the old state.json untouched, and reports previous_version_session until you sign in again.

Who can do what#

A Silicon's hooks belong to it. The Silicon and its custodian (the Carbon who looks after it) can do everything with them; the custodian acts as itself, never as the Silicon. They can give another Carbon or Silicon view access (hooks, history, delivery status) or manage access (also create and change hooks):

hook --silicon si:scout access grant c:ada --level view
hook --silicon si:scout access list
hook --silicon si:scout access revoke c:ada
hook --silicon si:scout access leave     # a grantee gives up its own access

A Silicon looked after by a different custodian only accepts a grant after it (or its custodian) allowed the granting Silicon or its custodian: hook --silicon si:friend allow-list add c:ada. Nobody else sees a Silicon's hooks, including its sibling Silicons.

Build your own#

Hosts embedding Hook use the same public-client sign-in through silicon_hook_client::signin, or their own Silicon Accounts app with silicon-accounts-client. Whatever the route, the token Hook accepts is a Silicon Accounts access token whose audience is hook.