Hook CLI#
The hook binary is built from crates/cli and uses silicon-hook-client for
all backend and local-service networking. Build it with
cargo build -p silicon-hook-cli; the executable is target/debug/hook.
For a published version use cargo install silicon-hook-cli --locked.
Maintainers bundle canonical docs/ guides into the crate with
python3 scripts/bundle-cli-docs.py before publishing; CI rejects stale copies.
First session#
Ask IAM for a short-lived token for tos>hook, then provide the token to Hook:
hook --profile cos iam --json
hook --profile cos --org tos login <slt>
hook --profile cos login status --json
hook --profile cos webhook http://127.0.0.1:9000/events
hook --profile cos --silicon cos:tos create GitHub
hook --profile cos --silicon cos:tos list
hook login <slt> is the short form required for agents. --slt-file - reads
from stdin, and --slt remains available for compatibility. Literal tokens can
appear in shell history/process arguments, so use a file or stdin when possible.
Hook does not request your
password, OTP or browser callback. Start the recipient server at the provided
URL before expecting delivery. The login response never prints session tokens.
A successful login saves tokens and a separate local API token, then starts the
persistent daemon and local request gateway. Configure delivery afterward with
hook webhook <webhook-url>. Until then, events stay pending. The optional
login --webhook-url <url> flag still configures delivery in the same command.
Silicon identities subscribe to their own stream automatically. A Carbon supplies
--silicon during login or uses hook daemon subscribe <silicon-id>... afterward;
IAM must authorize each Silicon.
hook iam --json discovers the actual backend-configured app_id, iam_url,
testing flag and login_method before login. With --test <id>, it discovers
that environment's IAM application using the locally attached Hook test key.
It never returns an app secret or environment key.
hook login status --json refreshes an expiring session, then checks the current
bearer and organization membership online with IAM. A successful response contains
authenticated: true, actor: {"type": "carbon" | "silicon", "id": "..."},
organization, expiry, and local delivery configuration. No saved session or an
invalid/revoked credential reports authenticated: false. Transport and permission
failures remain errors, so an outage is not reported as a successful login.
whoami remains an offline view of saved metadata.
hook webhook <webhook-url> sets or replaces the selected profile/environment's
recipient. It validates the URL locally, stores it beside the tokens, and starts
the daemon if needed. The destination is never sent to the backend. HTTP is
accepted only on loopback; remote recipients require HTTPS. Embedded credentials
and fragments are rejected.
hook unhook clears only the selected identity's recipient, retaining its login,
stream selection, and local request API. Other identities keep their destinations.
The daemon applies changes within five seconds and cancels old relay work;
in-flight requests may already have reached the old recipient. Events without
an acknowledgment replay after hook webhook <webhook-url> reconnects delivery.
Use hook logout to revoke authentication.
Context#
Global flags may appear before or after a command:
| Flag | Meaning |
|---|---|
--profile <name> |
Independent local identity and backend; default default |
--url <origin> |
Override service origin for a new/unbound profile |
--org <handle> |
Select the production or test organization |
--silicon <id> |
Silicon whose hooks/history/deliveries the action addresses |
--test <uuid> |
Select a saved IAM application sandbox and its separate test session |
--json |
Machine output with no contextual next-step prose |
--idempotency-key <key> |
Stable logical mutation identifier for retries |
SILICON_HOOK_URL and SILICON_HOOK_ORG provide origin/organization defaults.
A profile with credentials is bound to its backend. Use another profile for a
different backend; this prevents sending saved credentials to the wrong host.
Test commands never fall back to the production session. A signed-in Silicon
is the default target; a Carbon normally supplies --silicon.
State lives in ${SILICON_HOME:-~}/.silicon-hook/state.json. A nonempty
SILICON_HOME supplies the default base home. Set another base home with
hook config home <directory> (the state then lives below
<directory>/.silicon-hook). The location must already be a directory.
SILICON_HOOK_HOME remains an environment override for the complete state
directory. Directory mode is 0700 and files are 0600 on Unix. A process
lock serializes refresh and state updates, and replacement is atomic. Keep
this directory private: it contains access/refresh tokens and test root keys.
Do not share it between independent machines refreshing the same token family.
Before rotating a refresh token, the CLI saves an idempotency key in that
session. If the response is lost, retrying the command reuses this key. The key
is cleared only when the replacement tokens are saved successfully; the daemon
uses the same locked refresh path.
Command reference#
Run hook <command> --help for complete options and required arguments.
hook commands lists every command path; hook commands --json includes full
help. hook docs <topic> bundles these guides for offline reading.
| Command | Purpose |
|---|---|
iam --json |
Discover the public IAM app configuration before login |
login <slt> |
Save a session and start its local gateway (--slt-file and optional --webhook-url are supported) |
login status --json |
Check authentication and actor online with IAM |
webhook <webhook-url> |
Configure or replace local delivery for this identity |
unhook |
Detach local delivery while retaining authentication |
logout |
Revoke the refresh-token family and remove the selected local session |
whoami |
Show actor, organization, expiry and local recipient; no tokens |
create <name> |
Create a signed hook; optional description/time-zone/signature |
list [--include-deleted] |
List hooks and their current endpoints |
show <uuid> |
Read hook metadata and signature policy |
update <uuid> --patch <JSON-or-@file> |
Change metadata, activation or signature policy |
delete <uuid> / restore <uuid> |
Soft-delete or recover within 45 days |
enable <uuid>... / disable <uuid>... |
Atomically resume/pause several hooks |
rotate endpoint <uuid> |
Permanently retire the old URL and issue a new URL |
rotate secret <uuid> |
Invalidate the old signing secret immediately |
events [--hook <uuid>] [--limit N] [--cursor ...] |
Verified history, per hook or all hooks |
blocked [same filters] |
Withheld requests, separate from delivered history |
deliveries list [--limit N] [--after N] |
Pull retained pending deliveries |
deliveries ack <sequence> |
Cumulative acknowledgment for this identity/Silicon |
deliveries cursor |
Read the durable acknowledgment position |
connect-iam |
Register a Silicon's IAM webhook connection |
listen [--ack] |
Foreground stream inspection; Ctrl-C closes it |
system version / system health |
Compatibility and backend readiness |
env ... |
See the testing CLI guide |
daemon ... |
Persistent relay and local request interface |
config show / config profiles |
Inspect local settings and names |
config home <directory> |
Set the base home directory for local state |
config set <key> <value> |
Set url, org, silicon, auto-update, or telemetry |
Hook deliveries printed by listen and posted to the configured webhook use
{"type":"new_event","data":{"sender":"<provider>","metadata":{...}}}.
Event details, including the ACK sequence and captured request, are inside
data.metadata. See the complete relay format.
History limits are 1–10000, but a byte-bounded page may return fewer items.
Follow next_cursor until null. Delivery pull limit is at most 1000.
listen answers pings automatically. listen --ack ACKs after printing;
without it inspection fills the outstanding window and then waits. Use the
daemon for persistent recipient delivery and reconnect. A daemon using the same
identity may ACK events while you inspect that identity's foreground stream.
Signature examples#
hook --silicon cos:tos create GitHub --signature @github-policy.json
hook --silicon cos:tos create LocalDemo --unsigned
hook --silicon cos:tos update <uuid> --patch '{"description":null}'
hook --silicon cos:tos update <uuid> --patch '{"signature":{"required":true}}'
Create/secret-rotation/environment-key output can contain secrets; redirect
those responses into private files if retaining them. show never retrieves a
hook's original signing secret. Use rotation if that secret is lost.
See the signature reference for the
full expression grammar, algorithms and encodings. Default verification uses
HMAC-SHA256 over webhook-id.webhook-timestamp.raw-body and base64 signatures.
Daemon#
hook daemon start
hook daemon status
hook --profile reviewer daemon subscribe cos:tos helper:tos
hook --profile reviewer daemon token
hook --profile reviewer daemon request --file request.json
hook daemon stop
hook daemon run
run stays in the foreground and is suitable for a service manager. The
background daemon shares one loopback port across all profiles and environments.
Changes are picked up within five seconds. subscribe replaces a selected
identity's list; no IDs unsubscribes all. token intentionally prints a secret
for programs calling http://hook.localhost:18479/request.
The daemon log is ~/.silicon-hook/relay.log. Recipient failures retry without
acknowledging upstream. Logging out removes that identity from the daemon.
Stopping it leaves backend events pending. A machine reboot requires starting
the daemon again (login and daemon start do this); for boot-time startup run
hook daemon run through your operating system's service manager.
The local API guide defines request/receipt JSON, exact body echoes, identity tokens and downstream acknowledgment behavior.
Updates and troubleshooting#
Updates are enabled by default. After a command finishes, at most once per hour,
the CLI checks its crates.io release. Cargo-installed binaries update in their
existing installation root. Development/custom binaries get a release notice;
the updater does not overwrite source build outputs. A running daemon keeps its
loaded version until restarted. When upgrading from a build that required the
recipient during login, run hook daemon stop before using the new login or
delivery commands, then hook daemon start with the rebuilt CLI. The new CLI
reads existing recipient strings and also supports unconfigured recipients.
Opt out with hook config set auto-update off or
SILICON_HOOK_AUTO_UPDATE=false. Enable again with auto-update on. The CLI
stores the last-check timestamp and serializes the claim to avoid concurrent
installations. Update failures do not change the command's success/failure.
Common recovery steps:
- An expired/revoked session needs a fresh IAM SLT and
hook login. - A missing test key needs
hook env attachor authorizedhook env key. - A rotated key requires refreshing the saved key before test commands resume.
- A local port conflict needs resolving the process already bound to 18479.
- An offline recipient keeps deliveries pending; restart it at the saved URL.
- A JSON error includes a stable backend code; use
--idempotency-keyon retries after uncertain transport outcomes.
hook report and the graphical UI are outside the current release scope.
Bring your own secret (BYOS)#
Create with your provider's secret, or set it after registration:
hook create Stripe --signature @stripe-policy.json --secret-file provider-secret.txt
hook set-secret <hook-uuid> --secret-file provider-secret.txt
hook set-secret <hook-uuid> --secret-file encoded-secret.txt --secret-encoding hex
hook --test <environment-uuid> set-secret <hook-uuid> --secret-file -
--secret-file - reads stdin. Files preserve spaces and remove only one trailing
LF/CRLF. Empty, multiline, control-character, or over-4096-byte secrets fail.
create --signature configures verification and may itself contain secret;
do not also supply --secret-file in that case. Omitting a secret at creation
generates one. set-secret preserves the current encoding unless specified,
and preserves the URL, verification scheme and enabled/required settings.
The previous secret stops verifying immediately. Only creation/rotation prints
a secret; set-secret returns public hook metadata.
To update the scheme and secret together, use the existing merge patch:
hook update <hook-uuid> --patch @byos-patch.json
The file can contain {"signature":{"secret":"provider-secret","secret_encoding":"utf8"}}
alongside algorithm, payload, signature, and other policy members. These
commands work identically in production and paired testing environments.
Select an IAM sandbox#
Run hook env use --app-secret-file ./hook-test-app-secret, then hook login your-silicon:tos --webhook-url http://127.0.0.1:8080/events. The selector is validated online and never grants actor authority. Run hook env exit to restore the production session. --production uses production for one invocation. The active sandbox is printed after every command, error and help output. See testing instructions.
hook about prints project links. hook report "description" --pr https://github.com/teamofsilicons/silicon-hook/pull/123 submits an explicit issue using authenticated GitHub CLI. Diagnostic telemetry excludes report text.