Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
8752a9d
docs: describe agent authority and implementation follow-ups
jhrozek Oct 5, 2026
b5d5cc2
Creds lifetime changes
jhrozek Oct 6, 2026
3b4bd06
Update
jhrozek Oct 7, 2026
a12a097
docs: fix agent identity draft links after rebase
jhrozek Oct 8, 2026
2721b58
docs: introduce agent identity architecture overview
jhrozek Oct 9, 2026
7e7e42f
docs: consolidate agent identity design into focused chapters
jhrozek Oct 10, 2026
c6cf31e
docs: checkpoint agent credential and audit walkthrough
jhrozek Oct 12, 2026
36a22d3
docs: define Cedar MCP ceilings and audit evidence
jhrozek Oct 12, 2026
418c652
docs: add MCP gateway modes chapter for AS chaining
jhrozek Oct 12, 2026
f75b378
docs: retire superseded agent identity drafts
jhrozek Oct 12, 2026
c649be4
docs: consolidate agent identity chapter responsibilities
jhrozek Oct 12, 2026
fbf9e8d
docs: address agent identity review feedback
jhrozek Oct 13, 2026
8e7bdd0
Take the split-AS model into account
jhrozek Oct 14, 2026
e2e684a
docs: rework agent identity credential flow around AS-1 ID-JAG
jhrozek Oct 15, 2026
5b39578
docs: move D6 and D7 under Decisions in the rework record
jhrozek Oct 15, 2026
c872f08
docs: illustrate agent identity relationships and lifetimes
ChrisJBurns Oct 15, 2026
d830782
docs: separate host and broker sessions in the agent identity glossary
jhrozek Oct 15, 2026
54812e3
docs: describe the credential flow rework as a decision record
jhrozek Oct 15, 2026
d9fb3c0
docs: restore the definition loader as a broker module
jhrozek Oct 15, 2026
e4b9153
docs: show the definition loader in the relationships diagram
jhrozek Oct 15, 2026
eede8bd
docs: sequence identity work before authority work
jhrozek Oct 15, 2026
81eae38
docs: state that the broker does not own run admission
jhrozek Oct 15, 2026
adae397
docs: describe broker deployment and the threats it addresses
jhrozek Oct 15, 2026
5aec36d
docs: add sign-out and revocation to the identity work
jhrozek Oct 15, 2026
1a56af2
docs: define the audit evidence as an AuditEvent profile
jhrozek Oct 15, 2026
905f9e9
docs: record delegation lineage as retained audit events
jhrozek Oct 15, 2026
3557e50
docs: specify audit delivery, protection, and reconciliation
jhrozek Oct 15, 2026
f7c5f58
docs: fold the credential flow rework into the chapters
jhrozek Oct 15, 2026
ca5d9c1
docs: quote ID-JAG section 9.3 correctly
jhrozek Oct 15, 2026
467060b
docs: check that the token's user owns the session at open
jhrozek Oct 15, 2026
27a5065
docs: describe how the authority work contains a compromised mecak8s
jhrozek Oct 15, 2026
4790ce8
docs: record the run owner and keep shared sessions possible
jhrozek Oct 15, 2026
fcbff9a
docs: require lossless audit delivery where compliance demands it
jhrozek Oct 15, 2026
f340ce5
docs: add the ToolHive change for redeeming any AS-1 subject
jhrozek Oct 15, 2026
1c156d2
docs: make clear the definition loader is part of the identity broker
jhrozek Oct 16, 2026
b8f0e7b
docs: rewrite the agent identity overview for evaluators
jhrozek Oct 16, 2026
433bc0a
docs: move the threat table into a threat model chapter
jhrozek Oct 16, 2026
5adac4b
docs: restructure the agent identity overview
jhrozek Oct 16, 2026
59cd3f9
docs: tighten the overview and name the enterprise gateway case
jhrozek Oct 16, 2026
e437f25
docs: correct the credential flow and settle its open design gaps
jhrozek Oct 16, 2026
a383e11
docs: fix the credentials sequence diagram so it renders
jhrozek Oct 16, 2026
2bc800d
docs: settle delegation, registration, and provenance in the agent de…
jhrozek Oct 16, 2026
5aabd95
docs: give each credential hop its exact checks and failures
jhrozek Oct 16, 2026
a429ae1
docs: align run ownership in the agent definitions chapter
jhrozek Oct 16, 2026
35acb1f
docs: settle the credential flow's failure handling and edge cases
jhrozek Oct 16, 2026
2470851
docs: close the credential flow's revocation and session gaps
jhrozek Oct 16, 2026
17ae00f
docs: resolve the last contradictions in the credential flow
jhrozek Oct 16, 2026
0942964
docs: restructure the credentials chapter around one flow
jhrozek Oct 16, 2026
25969be
docs: restore facts the restructure dropped and fix its seams
jhrozek Oct 16, 2026
de4303c
docs: draw the README's trust boundaries explicitly
jhrozek Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Caller identity and audit records are useful building blocks, not a complete
tenant-isolation boundary. Cross-process cryptographic proof and authority
attenuation remain active design work. See the
[agent identity tracker](https://github.com/stacklok/mecatl/issues/377) and the
[working identity model](./docs/drafts/agent-identity-model.md).
[agent identity and authority design](./docs/drafts/agent-identity/README.md).

## Try it locally

Expand Down
7 changes: 7 additions & 0 deletions docs/architecture/domain-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ letting a restarted process rebuild the same per-session engine. `SessionKind` (
scheduled, subagent, parallel branch, team member, or debug) and `SessionRelationship`
record who produced the session; legacy data restores as `unknown`, which fails closed.

`SessionID` addresses the conversation; `session.IncarnationID` identifies this
lifetime of that ID. Restoration preserves the incarnation, while a newly created
session with a reused ID gets a new one. A host-supplied `RunID` identifies one
unit of work: fresh work gets a new ID, while approval or external-authorization
continuation retains the pending run's ID across restart. Engine callers may omit
`RunID`; it is a correlation label, not an authorization grant.

`Limits` and `Counters` drive the stop conditions; a zero limit disables that check.
`StopReason` is the loop's pre-turn guard and mixes the recorded reason with a limit
check, so persistence uses `RecordedStopReason` instead.
Expand Down
22 changes: 13 additions & 9 deletions docs/architecture/mecatl.modelith.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ A disposable harness instance — one running process — that loads `Sessions`

**Relationships**

- `Run` — 1:n — referenced — executes
- `Run` — n:n — referenced — executes — A paused run can continue in another process with the same run identity.
- `SessionLease` — 1:n — referenced — holds

**Invariants**
Expand Down Expand Up @@ -326,7 +326,7 @@ A session's evidence of the file versions it has read, stored independently of t

### `Run`

A single drive of a `Session` from a starting state to a terminal one — one invocation of the agent loop. A `Run` sequences `Turns`, emits a stream of `Events`, and ends with a stop reason (end-of-turn, budget, no-progress, cancelled, error). It is the execution, not the state: the `Session` it drives outlives it.
One unit of work driven through a `Session` by the agent loop. It sequences `Turns` and emits `Events`. It can pause awaiting approval or external authorization and continue with the same logical run identity, even if a new in-process loop handle drives the continuation. The `Session` outlives the `Run` and can host later runs.

**Relationships**

Expand All @@ -336,14 +336,14 @@ A single drive of a `Session` from a starting state to a terminal one — one in

**Invariants**

- **run-one-terminal-stop** — A `Run` drives its `Session` to exactly one terminal state and reports exactly one stop reason.
- **run-one-terminal-stop** — A paused `Run` has no terminal stop. Its continuation retains the same run identity; on completion it reports one terminal stop reason.

- **run-no-replay-after-first-chunk** — Once a `Turn` has streamed its first chunk, the `Run` never retries or replays that `Turn`.


### `Session`

The central aggregate and unit of work: a stateful conversation between a principal and a model, with an `Environment` binding, usage accounting, and limits. A `Session` is a state machine (idle, running, awaiting, completed, cancelled, failed) and is bound to one `Provider`. Its effective `Model` is fixed for each `Turn`; a `PermissionMode` change can re-resolve the model between turns within that provider. It survives process restarts when backed by a store.
The central aggregate: a stateful conversation between a principal and a model, with an `Environment` binding, usage accounting, and limits. A `Session` is a state machine (idle, running, awaiting, completed, cancelled, failed) and is bound to one `Provider`. Its effective `Model` is fixed for each `Turn`; a `PermissionMode` change can re-resolve the model between turns within that provider. It survives process restarts when backed by a store, preserving its incarnation identity across restoration.

**Relationships**

Expand All @@ -368,6 +368,8 @@ The central aggregate and unit of work: a stateful conversation between a princi

- **session-recover-before-reuse** — A `Session` in a terminal state (completed, cancelled, or failed) is returned to idle before any new `Run` reuses it.

- **session-incarnation-persists** — A `Session` has one incarnation identity for the lifetime of its ID. Restoration preserves it; a new `Session` reusing the ID gets a new incarnation.

- **session-usage-survives-restart** — Cumulative token usage is preserved across reopen, interrupt, recover, and process restart.


Expand Down Expand Up @@ -576,7 +578,7 @@ erDiagram
PermissionMode ||--|| Session : "posture of"
PermissionMode }o--|| Model : "selects via slot"
PermissionRule }o--o{ ToolCall : "authorizes"
Process ||--o{ Run : "executes"
Process }o--o{ Run : "executes"
Process ||--o{ SessionLease : "holds"
Provider ||--o{ Model : "offers"
ProviderDiscovery }o--|| Provider : "discovers metadata for"
Expand Down Expand Up @@ -1005,7 +1007,7 @@ erDiagram

- **run-no-replay-after-first-chunk** — Once a `Turn` has streamed its first chunk, the `Run` never retries or replays that `Turn`.

- **run-one-terminal-stop** — A `Run` drives its `Session` to exactly one terminal state and reports exactly one stop reason.
- **run-one-terminal-stop** — A paused `Run` has no terminal stop. Its continuation retains the same run identity; on completion it reports one terminal stop reason.


### A session resumes after a restart at a pending ask
Expand All @@ -1015,12 +1017,14 @@ erDiagram
**Steps**

1. A `Session` is parked on a `PermissionAsk` when the process dies; the `EventLog` holds every `Event` up to that point.
2. `Operator` restarts the harness; a new `Process` recovers the `Session` to idle before reuse, preserving cumulative usage.
3. `Client` approves the pending ask; the `Run` re-enters the loop at the ask and the pending `ToolCall` executes exactly once.
2. `Operator` restarts the harness; a new `Process` restores the awaiting `Session`, preserving its incarnation, run identity and cumulative usage.
3. `Client` approves the pending ask; the same logical `Run` continues at the ask and the pending `ToolCall` executes exactly once.

**Invariants touched**

- **session-recover-before-reuse** — A `Session` in a terminal state (completed, cancelled, or failed) is returned to idle before any new `Run` reuses it.
- **session-incarnation-persists** — A `Session` has one incarnation identity for the lifetime of its ID. Restoration preserves it; a new `Session` reusing the ID gets a new incarnation.

- **run-one-terminal-stop** — A paused `Run` has no terminal stop. Its continuation retains the same run identity; on completion it reports one terminal stop reason.

- **event-log-records-terminal-tail** — The `EventLog` records every `Event` a `Run` emits, including the terminal result emitted after a `Client` disconnects.

Expand Down
36 changes: 21 additions & 15 deletions docs/architecture/mecatl.modelith.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ glossary:
entities:
Session:
definition: >
The central aggregate and unit of work: a stateful conversation between a
principal and a model, with an `Environment` binding, usage accounting, and
limits. A `Session` is a state machine (idle, running, awaiting, completed,
The central aggregate: a stateful conversation between a principal and a
model, with an `Environment` binding, usage accounting, and limits. A
`Session` is a state machine (idle, running, awaiting, completed,
cancelled, failed) and is bound to one `Provider`. Its effective `Model`
is fixed for each `Turn`; a `PermissionMode` change can re-resolve the model
between turns within that provider. It survives process restarts when
backed by a store.
backed by a store, preserving its incarnation identity across restoration.
relationships:
- entity: Conversation
cardinality: "1:1"
Expand Down Expand Up @@ -110,6 +110,11 @@ entities:
statement: >
A `Session` in a terminal state (completed, cancelled, or failed) is
returned to idle before any new `Run` reuses it.
- id: session-incarnation-persists
statement: >
A `Session` has one incarnation identity for the lifetime of its ID.
Restoration preserves it; a new `Session` reusing the ID gets a new
incarnation.
- id: session-usage-survives-restart
statement: >
Cumulative token usage is preserved across reopen, interrupt, recover,
Expand Down Expand Up @@ -157,11 +162,11 @@ entities:

Run:
definition: >
A single drive of a `Session` from a starting state to a terminal one —
one invocation of the agent loop. A `Run` sequences `Turns`, emits a stream
of `Events`, and ends with a stop reason (end-of-turn, budget, no-progress,
cancelled, error). It is the execution, not the state: the `Session` it
drives outlives it.
One unit of work driven through a `Session` by the agent loop. It sequences
`Turns` and emits `Events`. It can pause awaiting approval or external
authorization and continue with the same logical run identity, even if a
new in-process loop handle drives the continuation. The `Session` outlives
the `Run` and can host later runs.
relationships:
- entity: Session
cardinality: "n:1"
Expand All @@ -178,8 +183,8 @@ entities:
invariants:
- id: run-one-terminal-stop
statement: >
A `Run` drives its `Session` to exactly one terminal state and reports
exactly one stop reason.
A paused `Run` has no terminal stop. Its continuation retains the same
run identity; on completion it reports one terminal stop reason.
- id: run-no-replay-after-first-chunk
statement: >
Once a `Turn` has streamed its first chunk, the `Run` never retries or
Expand Down Expand Up @@ -864,9 +869,10 @@ entities:
`Session` from its snapshot plus the `EventLog`.
relationships:
- entity: Run
cardinality: "1:n"
cardinality: "n:n"
ownership: referenced
role: executes
note: A paused run can continue in another process with the same run identity.
- entity: SessionLease
cardinality: "1:n"
ownership: referenced
Expand Down Expand Up @@ -1110,10 +1116,10 @@ scenarios:
actors: [Operator, Client]
steps:
- "A `Session` is parked on a `PermissionAsk` when the process dies; the `EventLog` holds every `Event` up to that point."
- "`Operator` restarts the harness; a new `Process` recovers the `Session` to idle before reuse, preserving cumulative usage."
- "`Client` approves the pending ask; the `Run` re-enters the loop at the ask and the pending `ToolCall` executes exactly once."
- "`Operator` restarts the harness; a new `Process` restores the awaiting `Session`, preserving its incarnation, run identity and cumulative usage."
- "`Client` approves the pending ask; the same logical `Run` continues at the ask and the pending `ToolCall` executes exactly once."
invariants_touched:
[session-recover-before-reuse, event-log-records-terminal-tail, ask-suspends-run-until-resolved, session-usage-survives-restart, rehydrate-tool-exactly-once]
[session-incarnation-persists, run-one-terminal-stop, event-log-records-terminal-tail, ask-suspends-run-until-resolved, session-usage-survives-restart, rehydrate-tool-exactly-once]

- name: A rehydrated session does not re-ask a previously granted tool
actors: [Operator, Client]
Expand Down
4 changes: 2 additions & 2 deletions docs/drafts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ rely on them for how Mecatl works.

| File | Author | Summary | Decide by (keep, move to an issue, or delete) |
|---|---|---|---|
| [agent-identity-model.md](agent-identity-model.md) | Juan Antonio Osorio | Strawman for agent identity: Mecatl as its own SPIFFE trust domain with JWT delegation chains. | **2026-11-06** |
| [agent-identity-outbound.md](agent-identity-outbound.md) | Juan Antonio Osorio | Part 2 of the identity model: how the harness reaches tools and gateways on the outbound hop. | **2026-11-06** |
| [agent-identity/README.md](agent-identity/README.md) | Juan Antonio Osorio | Proposed broker-centered agent identity, authority, audit, and credential lifecycle. | **2026-11-06** |
| [agent-identity-outbound.md](agent-identity-outbound.md) | Juan Antonio Osorio | Historical companion to the former identity model: how the harness reaches tools and gateways on the outbound hop. | **2026-11-06** |
| [cloud-native-harness-kit.md](cloud-native-harness-kit.md) | Juan Antonio Osorio | Positioning definition of the cloud-native harness kit and where its responsibility ends. | **2026-11-06** |
| [cloud-native-harness-systems.md](cloud-native-harness-systems.md) | Joe Beda | Speculative scoping of open questions for cloud-native harness systems. | **2026-11-06** |
| [scoped-resource-grants.md](scoped-resource-grants.md) | Joe Beda | Strawman for short-lived, attenuable grants and direct tool-to-service data paths. | **2026-11-06** |
Expand Down
Loading
Loading