Quickstart · two commands, no account
Local approvals in 2 commands. A signed receipt for each decision you make.
What is published today is the lite daemon, @synoi/gateway-lite. It runs on your own machine, takes a governed action from your code, holds it until you approve or deny it, and signs that decision with a key generated locally that is never transmitted. No account, no payment, and no network call needed to run it.
Scope, so you can judge it before installing: the lite daemon leaves out the channel adapters, the license client, and managed-custody signing by construction rather than by policy, and its own README labels it PARTIAL and suitable for local dogfood. Against the open conformance suite the gateway records Tier 2, 118 of 137 vectors, with L1 and L2 passing and L3 and L4 not tested. See the GAP page for the breakdown.
STEP 01
Run the daemon
Starts the lite daemon on your machine. Open the dashboard to enroll your operator identity: that keypair is generated in the browser with Web Crypto and its private key stays there.
npm i @synoi/sdk npx @synoi/gateway-lite # Daemon: http://127.0.0.1:8787 (override with SYNOI_LITE_PORT) # Dashboard: http://127.0.0.1:8787/local/dashboard
STEP 02
Wrap an action with gate()
The wrapped function is held until you approve or deny the action in the dashboard. Deny it and the function does not run. If you would rather not take the SDK, POST the same payload to /local/gate.
import { gate } from '@synoi/sdk'
await gate({
action_kind: 'command',
args: { to: 'ops@example.com', subject: 'deploy complete' },
daemonUrl: 'http://127.0.0.1:8787', // or SYNOI_DAEMON_URL
}, async () => {
// runs only after you approve it in the dashboard
await sendEmail()
})STEP 03
Verify the receipt offline
The decision is self-signed with your operator key under the synoi.receipt/gap-selfsign scheme, and checks out with no network call. Read the disclosure below before you describe that receipt to anyone else.
import { verifyReceiptByScheme } from '@synoi/verify'
// receipt fetched from GET /local/receipts/:oid
const result = await verifyReceiptByScheme({
receipt,
gap_ed25519_pub: pubkey,
})
// result.valid === true
// result.scheme === 'gap-selfsign'What that verification does and does not prove
It proves the receipt was signed by the key on your machine and has not been altered since. It does not prove to anyone else that the key belongs to a party they should trust: the neutral third-party resolver for that (oid.synoi.systems) is planned and not live. So a self-signed receipt should not be called independently verified. The key also has no managed custody and no recovery: any process running as your OS user can sign as the operator, and if the key is lost there is no SynOI-side way to get it back.
What you have, after five minutes
A local approve/deny gate
Actions wait on your decision. Deny one and the wrapped code does not run at all.
Self-signed decision receipts
Ed25519 under the synoi.receipt/gap-selfsign scheme, checkable offline with @synoi/verify.
An operator key you hold
Generated once on your machine and never transmitted. Wrapped with DPAPI on Windows, Keychain on macOS, secret-tool on Linux where a secret service is running.
No account, no phone-home
Nothing to sign up for, and the daemon needs no network call to run.
No custody, and no recovery
Any process running as your OS user can sign as the operator. Lose the key and it is gone; past receipts cannot be re-signed under a continuous identity.
Not the full gateway
Channel adapters, the license client, and managed-custody signing are absent from this package, verified in the source repo's CI rather than by inspection.