Capabilities
How Qosm's capability-based security model works.
Most agent frameworks take the same approach to security: give the agent access to everything, then try to prevent misuse. Sandbox it. Check permissions at runtime. Filter the inputs.
Qosm inverts this entirely.
Positive security
Instead of asking "what should the agent not do?", Qosm asks: "what should the agent be able to do?"
A Qosm program can only call functions that the host explicitly provided. There's no import, no require, no filesystem access, no network access — unless you gave it a function for that.
// The host provided exactly two functions:
extern http_get : {url: String, headers: Array<{key: String, value: String}>}
-> Result<String, QosmError> ! {Http.Get};
extern db_insert : {key: String, value: String}
-> Result<Unit, QosmError> ! {Db.Insert};
// This is ALL the agent can do.
// No filesystem. No arbitrary network. No LLM unless the host adds one.
let fetch_and_store url key =
match http_get {url: url, headers: []} with (
| Ok{value: body} -> db_insert {key: key, value: body}
| Err{value: e} -> Err{value: e});
This isn't enforced by a runtime check that might have holes. It's enforced by the compiler. If the code references a function that wasn't declared, it doesn't compile. Period.
The capability manifest
The list of extern declarations in a Qosm program is its capability manifest — a complete, machine-readable description of what the code can do. You can read it and know, with certainty, the full scope of the agent's power.
Compare this to a typical agent framework where you have to audit runtime logs, trust that permission checks are correct, and hope the LLM doesn't find a creative way around them.
Credentials stay outside
When you create a capability set in the workspace (e.g., http_get scoped to api.github.com with a Bearer token), the credentials are stored on the server and injected at runtime. The agent code never sees the API key, can't log it, can't exfiltrate it. The code only sees a function called github_get that takes a URL and returns a response.
// The agent sees this:
let repos = github_get {url: "https://api.github.com/repos/myorg/myapp", headers: []};
// The agent CANNOT see:
// - the Bearer token
// - that the domain is restricted to api.github.com
// - that other GitHub endpoints are blocked
Composition is transparent
When two capabilities compose, their effects merge:
let pipeline text =
match api_get {url: "https://api.example.com/data", headers: []} with (
| Ok{value: body} ->
my_claude @{summary: String} `Summarize: {{ body }}`
| Err{value: e} -> Err{value: e});
// Inferred type: String -> Result<{summary: String}, QosmError> ! {Http.Get, LLM.Call}
The type signature tells the full story. No hidden side effects, no surprises. We'll look at effects in more detail in the next chapter.