Authority Builder and XAL, authority as code¶
Phase 6 of the Authority Control Plane gives a workspace's authority a text form. XAL, the Xybern Authority Language, is a YAML document (with an identical JSON form for the API) that names the principals, their passports and boundaries, the roles, the missions, the mandates with their primitives, the communication rules, the delegations, the windows, the warrants, the flow labels and the tools of a workspace. It is validated against the same invariants every decision checks, compiled only into the objects that already exist, signed and versioned like a Charter version, and exported from any live workspace. The Authority Builder in the dashboard is a view over that text: it never has objects of its own.
Text comes first. A reviewer reads a diff, a pull request carries the file, the CLI applies it, and the canvas is a rendering.
A document¶
xal: 1
name: Procurement desk
principals:
- id: procurement-buyer
name: Procurement Buyer
department: Procurement
declared: {environment: production, risk_class: medium}
roles: [buyer]
boundary:
allowed: [read_*, create_quote, send_email, sign_contract]
disallowed: [transfer_*, payment*, export_*]
on_violation: block
status: active
roles:
- key: buyer
allowed: [read_*, create_quote, send_email, sign_contract]
denied: [transfer_*]
missions:
- key: renew_acme
principal: procurement-buyer
objective: Renew the Acme supplier contract at or below last year's price
allowed_outcomes:
- {outcome: research suppliers, capabilities: [read_*, search_*], order: 1}
- {outcome: sign the renewal, capabilities: [sign_contract], max_amount: 250000, order: 2}
forbidden_outcomes:
- {outcome: move money, capabilities: [transfer_*, payment*, wire_*]}
financial: {max_single_amount: 250000, currency: SAR}
lifetime_hours: 72
mode: enforce
mandates:
- key: no_irreversible_without_person
outcome: Nothing irreversible happens without a person
level: department:Procurement
primitives:
- {type: effect, action_types: ["*"], decision: escalate, conditions: {kinds: [delete], irreversible: true}}
communication:
default: escalate
rules:
- {from: procurement-planner, to: procurement-buyer, decision: allow, types: [instruction, delegate]}
delegations:
- {from: procurement-planner, to: procurement-buyer, action_types: [read_*, create_quote], scopes: ["procurement:*"], budgets: {max_actions: 200}, max_depth: 2, expires_hours: 720}
warrants:
- {principal: procurement-buyer, families: [read_*, create_quote], budgets: {max_actions: 50}, ttl_seconds: 7200, mission: renew_acme}
flow_labels:
- {kind: tool, key: supplier_db, class: CONFIDENTIAL, pii: false, origins: [SA]}
tools:
- {name: create_quote, schema: {type: object, properties: {amount: {type: number}}}}
Every section is optional. Keys (id for principals, key for roles, missions and mandates, and derived keys for the rest) make apply idempotent: applying the same document twice changes nothing.
Principals are named, not numbered¶
An agent id is unique across a deployment, and a document is written to be applied in more than one workspace. So a principal a document names, soc-lead, means in order: the agent of this workspace with that id, the agent of this workspace with that name, or the agent this document created here before. When the id is taken in another workspace, apply creates the agent as soc-lead-<6 hex> and keeps soc-lead as its name. Every reference in the document (communication rules, delegations, missions, warrants, windows, agent-level mandates) follows the same resolution, and the result of apply lists what each name resolved to under principals. The SDK matches the agents in your code to these by name.
What each section compiles to¶
| Section | Objects (nothing new is invented) |
|---|---|
principals |
registered agents; department membership; the passport declaration (declared); role assignments; an access profile as the boundary |
roles |
agent roles (allowed and denied families, scopes, delegation depth) |
missions |
intent contracts with an explicit mission spec, approved by the applier, no model involved |
mandates |
signed mandates with hand-written primitives, compiled into rules, sealed into the Charter as a new version |
communication |
the workspace default and the communication rules |
delegations |
delegation grants (tagged as XAL-managed) |
windows |
temporal permission windows |
warrants |
standing warrants issued with the narrowing and constraints named, bound to the mission when one is named |
flow_labels |
flow source labels |
tools |
tool schemas |
The primitive types and decisions of a mandate are exactly those of the Charter compiler (action_type, metadata, argument, semantic, verdict, sequence, inbound_stamp, obligation, dual_control, flow, effect, and the rest), so a document written by hand and a Charter compiled from prose land in the same rules.
Validate, plan, apply, export¶
Validation checks references (a role a principal names, a mission a warrant names), shapes (mission specs, constraints, on_match outcomes, passport declarations) and the invariants: a delegation chain or a warrant that would be wider than what its principal received is refused by INV-001 before anything is created. Warnings name references to things the document does not define but the workspace may already hold.
plan compares the document with a live export of the workspace and lists what apply would create or update. apply needs a person (an admin in the dashboard, or an API key with the approvals scope) and returns the result with the version it recorded. export writes the live workspace as XAL, including objects that were never created through XAL, so any workspace can be moved to text.
xybern xal templates
xybern xal validate procurement.xal.yaml
xybern xal plan procurement.xal.yaml
xybern xal apply procurement.xal.yaml --name "procurement desk v1"
xybern xal export > live.xal.yaml
xybern xal versions
xybern xal rollback --version 3
The same operations over HTTP, with a YAML body (Content-Type: application/x-yaml) or JSON ({"doc": {...}}):
POST /v1/enforce/xal/validate
POST /v1/enforce/xal/plan
POST /v1/enforce/xal/apply approvals scope; {"name": ..., "prune": false}
GET /v1/enforce/xal/export?format=yaml|json
GET /v1/enforce/xal/versions
GET /v1/enforce/xal/versions/<n>?format=json|yaml
POST /v1/enforce/xal/versions/<n>/rollback approvals scope
GET /v1/enforce/xal/templates
The Python SDK mirrors them: client.xal_validate(doc), xal_plan, xal_apply(doc, name=, prune=), xal_export(as_json=), xal_versions(), xal_version(n), xal_rollback(n), xal_templates().
Versions, diff, rollback¶
Every apply records a version: the document, its canonical hash, a per-workspace HMAC signature over {workspace_id, version, doc_hash, parent_version, applied_by}, the semantic diff against the previous version (added, removed and changed keys per section) and the apply result, and seals an entry in the Provenance Vault. Rollback re-applies an earlier version with pruning: the XAL-managed mandates, missions, communication rules and delegations that the restored version does not name are retired, the current version is marked rolled_back, and the restoration is itself a new version. The XAL view in the dashboard lists the versions with their diffs, shows any version's YAML and opens it in the Builder.
The Builder¶
The Builder (Build, Authority Builder) is a YAML editor with a canvas beside it. The document is validated as you type; the canvas renders it in five columns (roles and departments, principals, missions and authority, rules, resources and tools) with the delegations and communication rules drawn between principals. Selecting a card names the objects it compiles to and shows its fragment; after Plan, each card carries create, update or unchanged. Templates for a procurement desk, a payments desk, customer support and HR operations are XAL documents; "From the live workspace" loads the export. Apply asks for a confirmation and records the version; Attack runs the evasion scenarios of Attack System against the live Charter for the principals the document names.
Format¶
The document format is xybern-xal-v1. Its JSON Schema is published in the formats bundle as spec/xybern-formats-v1/xal-v1.schema.json, with a well-formed vector in vectors/xal.json. Canonicalisation of the document for hashing is the bundle's canonical JSON.