Synsema is a language where permission is syntax. The platform runs your agent under exactly what it declared, seals its secrets, and keeps the audit your security team will ask for.
Deploy your first agent See the API
Free for one service. Bring your own LLM key. The language is open source.
What runs here
Sites, APIs, server-rendered pages. One process serves HTML to people and Markdown to agents.
Expose tools to Claude, Cursor or any client. One route, secrets sealed, input under a ceiling.
No URL. Watch feeds, queues, chains, inboxes. Always on, under the same ceiling.
Blackboard, signals, spawn. Many agents in one process, one manifest for all of them.
EVM, Solana, Bitcoin, Algorand. Signing and spending are capabilities, metered and audited.
A PWA with native push, or a desktop binary. Same program, same fence.
Before it runs
Every deploy intersects what the code declares with require and what your plan permits. The result is a table, not a policy: this line granted, this line denied, and why. The program can never rise above it, because the runtime enforces the ceiling on every call.
| Declared in the program | Scope | On the Free plan |
|---|---|---|
| require net("rpc.arc.network") | rpc.arc.network | granted |
| require llm | — | granted |
| require secret("ARC_HOT_KEY") | ARC_HOT_KEY | granted |
| require sign("ARC_HOT_KEY") | ARC_HOT_KEY | denied · above the plan |
| require spend("USDC") | USDC | denied · above the plan |
| require memory("invoice-agent") | invoice-agent | granted |
While it runs
Every capability check the runtime performs, granted or denied, is written down with its origin and its reason. When an agent tries to read the cloud metadata address it never declared, the line is there, in red, with the refusal. That is the page a CISO opens first, and the one that closes the deal.
| 14:02:11 | sign | ARC_HOT_KEY | granted | invoice #2291 · 412 USDC |
| 14:02:10 | spend | USDC | granted | 412 / 500 |
| 13:58:40 | net | 169.254.169.254 | denied | never declared |
| 13:58:39 | llm | — | granted | reason · 1,930 tokens |
| 13:58:38 | secret | ARC_HOT_KEY | granted | sealed · never printed |
What it never sees
A secret() is opaque to the program that holds it. It authenticates, signs and pays, but it cannot be printed, logged, serialized or handed to a model. Prompt injection has nothing to steal, and your security review has one less question.
require secret("ARC_HOT_KEY") require sign("ARC_HOT_KEY") let key be secret("ARC_HOT_KEY") print(key) -- what the model would love to see let sig be secp256k1_sign(digest, key) -- what it is allowed to do
Built to be delegated
The whole permission surface is a block at the top of the file. Reviewed in a pull request, diffed between versions, readable by an auditor in twenty lines.
A runner is a machine with Docker and one program. It only calls out to the control plane, so putting it in your tenant gives us access to nothing of yours.
Enterprise services sit behind your SSO from the first deploy, with roles per project and an audit that goes to your SIEM. The confidential tier, in a TEE, is next.
Recipes
From the blog
Telling a model "never call external APIs" is a request. A manifest the runtime enforces is a guarantee. What changes when permission is syntax, and why security teams say yes to one and no to the other.
A walkthrough of the invoice-agent recipe: how the manifest, the spend ledger, the sealed signing key and the approval step fit together, and what the audit log looks like after the first payment.
Most agent secret leaks are not clever. The model was asked for the key and it had the key. Sealed secrets remove the second half of that sentence, and change what a security review has to check.
One command, a URL, and a record of everything the program was allowed to touch. Start free, bring your own key.