Identity
How OAS DIDs identify callers, how MACS verifies them, how lineage roots back to a human, and how capability sets are derived.
MAP does not own identity. It consumes OAS — the Open Agent Specification, a vendor-neutral W3C-DID standard. Every entity in the mesh has a did:oas:<namespace>:<kind>:<identifier>.
The DID
A typical caller DID:
did:oas:l1fe:agent:0xa3f9c1a4b5...Components:
| Segment | Meaning |
|---|---|
did | W3C DID scheme |
oas | The OAS method |
l1fe | The namespace (typically the organization) |
agent | The entity kind — one of 11 (see below) |
0xa3f9c1a4b5... | The unique identifier (Ed25519 public key digest) |
Entity kinds
OAS defines 11 entity kinds. MAP groups them as root vs derived:
| Root kinds | Derived kinds |
|---|---|
HumanRoot | Agent · AgentInstance |
MultiHumanRoot | Tool · Skill · Workflow |
EntityNameRecord | Model · Dataset · Service |
Every derived entity's lineage chain must terminate at a root. The chain is cryptographically signed at each step using HKDF-SHA256 derivation from the parent's Ed25519 key.
Lineage
Lineage is the mechanism by which autonomous actions remain accountable to a human. Every Agent derives from a HumanRoot through one or more derivation steps. The lineage proof is:
Root pubkey → signs → Child pubkey → signs → ... → Caller pubkeyThe proof is offline-verifiable. Given the chain and the leaf signature, any verifier can confirm the chain without contacting any server. MACS::verify_response does exactly this.
This is why MAP can run sovereign deployments. The audit chain plus the lineage chain plus the OAS root means an air-gapped institution can verify every action it has taken without a network connection.
Conformance levels
pub enum ConformanceLevel { L0, L1, L2 }| Level | Requirement | Use |
|---|---|---|
| L0 | DID exists; no lineage required | Sandbox tier, public read-only operations |
| L1 | Lineage verified for non-root entities | Standard production calls — most operations |
| L2 | L1 + full extended sections (attestations, reputation) | Charter-level governance, cross-org settlement |
MAXIM policies typically read the conformance level and require L1 or L2 for state-changing operations. Heavy agents (MARC::reasoning_task, MAGI::trace) require L1 minimum.
Capability sets
A resolved identity carries an AgentCapability set:
pub struct AgentCapability {
pub name: String, // e.g. "map.macs.auth_negotiation"
pub expires_at: Option<chrono::DateTime<Utc>>,
pub limits: Option<CapabilityLimits>,
pub caveats: Vec<String>,
}The capability name is a dotted path. The security gateway matches hierarchically:
| Match level | Example |
|---|---|
| Exact | map.macs.auth_negotiation |
| Protocol wildcard | map.macs.* |
| Global wildcard | map.*.* (reserved for admin/ops) |
A capability can carry caveats — additional constraints like time-of-day, jurisdiction, max spend per call. The gateway evaluates caveats at request time using the cedar-style policy engine in MAXIM.
How capabilities are acquired
Three sources:
- Declared on the DID document. Static capabilities baked into the OAS document for the entity.
- Delegated via
Aegis::delegate. A delegation token from a parent entity, bounded by the no-amplification rule (the delegate cannot exceed the delegator's authority). - Granted by treaty via
MOAT. A cross-org treaty grants the foreign caller a bounded capability set within your tenant.
MACS::derive composes all three sources at request time and produces the effective capability set the gateway checks.
Revocation
An identity can be revoked at any time:
- Static revocation via the OAS document (the DID document is updated;
MACS::verify_responseconsults the latest) - Delegated revocation via
Aegis::delegate(the delegation token includes revocation hooks) - Treaty revocation via
MOAT::terminate(cross-org capabilities evaporate immediately)
When an identity is revoked, in-flight requests complete; new requests deny at security gating. MERIT credentials issued to the revoked identity are not automatically revoked — that requires a separate MERIT::revoke call under authority.
Local admin (dev only)
ResolvedAgentIdentity::local_admin() exists for dev mode. It returns an identity with map.*.* capability and lineage_verified = true. Production gateways never issue this — production tenants are bound to specific capability sets only.
// Dev mode only:
let ctx = InvokeContext {
resolved_identity: Some(ResolvedAgentIdentity::local_admin()),
..Default::default()
};Reading identity inside a protocol module
async fn invoke(&self, op: &str, payload: Value, ctx: &InvokeContext)
-> Result<Response, ProtocolError>
{
let id = ctx.identity().ok_or_else(|| ProtocolError::PolicyDenied {
reason: "unresolved identity".into()
})?;
// For sensitive operations, require verified lineage:
if !ctx.caller_lineage_verified() {
return Err(ProtocolError::PolicyDenied {
reason: "verified lineage required".into()
});
}
// Enforce kind constraint (e.g. only autonomous orgs can convene MACE):
if id.entity_kind != AgentEntityKind::Agent && !id.is_autonomous_org() {
return Err(ProtocolError::PolicyDenied {
reason: "agent or autonomous org required".into()
});
}
// ... continue
}The helpers ctx.identity(), ctx.caller_lineage_verified(), id.has_capability("..."), and id.is_autonomous_org() are the four most common reads.
See also
- MACS — the verifier
- OAS adapter — the resolver
- Aegis adapter — delegation and key management
- Capabilities — the full capability model