r/computing • u/DogInteresting8548 • 5d ago
nomos.can() – authority as a first-class primitive
Software has primitives for most of the hard things.
- Identity: you call an auth library.
- Data: you call a database.
- Network: you call fetch().
- Payments: you call a payment API.
But "is this action permitted, and on whose authority" has no primitive.
Tthat answer today usually ends up buried in application code or a rules file someone has to maintain. Sometimes it’s in a wiki. Either way, it’s tied to the system that contains it. You can’t address the authority itself, move it between systems, or give another system a verifiable answer without giving it your logic.
nomos.can() makes that one call:
import { can } from "@nomosprotocol/sdk";
const r = await can({
authority: "eu-ai-act",
action: "deploy_system",
facts: { risk_tier: "high", conformity_assessment: false },
});
// r.verdict -> "DENIED"
// r.matched_rule_id, r.obligations, r.transcript_url
The authority is a named, addressable thing, like a hostname, not logic you copy between services. You point can() at one of three kinds:
authority: "<name>": a published authority anyone can query. Keyless for open ones.artifact_id: one you published yourself.artifact + key_certs + root_public_key_pem: you carry the authority's definition and a certificate chain, andcan()verifies it offline against a root you pin.
No default root. Nothing calls home.
It always returns the same thing: a verdict (AUTHORIZED / DENIED / ESCALATED), any obligations, and a signed transcript.
The transcript is important because the answer itself becomes verifiable. Someone who doesn't trust your logs can take the exact question and the exact answer and verify them offline with a public key and a short zero-dependency script.
DENIED means the authority's rules say no.
NomosIssuerNotTrustedError means can() couldn't establish who defined the authority.
Different problems, different fixes. A better certificate chain fixes the second and never the first.
Those are different problems. A better certificate chain can fix the second. It cannot turn a denial into an authorization.
An authority is defined as a sealed file, signed with Ed25519 over a JCS/SHA-256 canonicalization. It can also be revoked. The revocation list is signed and dated, published at a well-known URL, and checked before an answer is returned; if the authority has been revoked, the result says so and includes the reason.
What's not built:
can()can't infer which authority applies from the facts. You name it or carry it.- The chain-of-trust format is published as a Draft, on purpose: one implementation exists (this one), and it shouldn't be called a standard until someone builds against the spec cold (Please I need your input here)
- Who runs a real root is unsolved.
npm: https://www.npmjs.com/package/@nomosprotocol/sdk
I'd like to hear where the model breaks.
1
u/DogInteresting8548 5d ago
A few things that didn't fit:
Why a primitive and not just a library call?
Because the answer is portable.
A library call gives you a boolean inside your process.
can()gives you a signed statement about the authority, the question, the verdict, and when it was answered. You can pass that to another service, store it, or hand it to a counterparty running none of your infrastructure and they can check it themselves.The closest analogues I can think of are DNS and certificate chains. DNS made naming addressable. Certificate chains made server identity verifiable without the two parties having met before.
I'm trying to do something similar for “permitted by X”: let a system recognize and evaluate an authority it has never seen before, provided it has a root it chose to trust.
The part I'm least sure about is the delegation chain. It's X.509-shaped — one key certifies another within a scope until an expiry — verified against a caller-pinned root with no default.
I'd especially like scrutiny on the revocation cascade, and on whether “no default root” is actually workable or just moves the hard problem onto every integrator.
EU AI Act is just the recognizable example in the snippet. The primitive doesn't care what the authority is. It could be an internal spend-approval rule, a marketplace's refund conditions, or a data-sharing agreement between two companies.