Revise the proposed engine rule so a store may serve several engines.
An engine enables one capability through a consistent interface. It is not the store's only client and it is not an access-control mechanism. ADR-015 stays proposed. Assistant: grok Assistant-Session: 01a1609f-72b8-7222-9dff-fae300115e42
This commit is contained in:
parent
ae75aa4376
commit
87787807fa
2 changed files with 98 additions and 59 deletions
|
|
@ -107,30 +107,34 @@ Two boundaries are lexical as well as architectural:
|
|||
|
||||
### 2.2 Engine
|
||||
|
||||
An engine is the deterministic processor for one domain, as proposed in
|
||||
[ADR-015](docs/adr/ADR-015-engine-is-a-processor.md). The canon states the
|
||||
domain. The engine implements it. Tooling holds the records. The engine owns
|
||||
the record type and is the only admitted client of its store.
|
||||
An engine is a tool of automation for one capability, as proposed in
|
||||
[ADR-015](docs/adr/ADR-015-engine-is-a-processor.md). It encapsulates the
|
||||
complexity of that capability in a consistent, often simpler interface than
|
||||
doing the work by hand. The same inputs yield the same result, which reduces
|
||||
failure modes and makes the work more reliable and more efficient. The canon
|
||||
states the domain. The engine implements the capability. Tooling holds the
|
||||
records. Several engines may use one store, each for a different capability.
|
||||
|
||||
One library has three manifestations. The library performs the domain
|
||||
operations. The CLI runs that library in a process. A service is the same
|
||||
process kept running for one scoped environment. At start, that process is
|
||||
injected with the credential for that environment alone. The credential is how
|
||||
the process reads its inputs and writes its outputs. Callers do not receive it.
|
||||
An engine enables that capability. It is not an access-control mechanism.
|
||||
Restricting who may act remains access-engine's domain.
|
||||
|
||||
One library has three manifestations. The library performs the capability.
|
||||
The CLI runs that library in a process. A service is the same process kept
|
||||
running for one scoped environment. At start, that process is injected with
|
||||
the credential for that environment alone. The credential enables the
|
||||
capability. Callers do not receive it.
|
||||
|
||||
An operator is a Staff actor who starts or calls an engine. Authentication
|
||||
establishes who the operator is. Permission to use one named instance, or a
|
||||
named set of instances, is an access rule rendered by access-engine. The
|
||||
engine enforces that result and does not decide it. Holding the use-privilege
|
||||
does not confer the injected credential, and it does not authorize every
|
||||
operation the domain can perform. The engine still applies its deterministic
|
||||
rules to each call.
|
||||
named set of instances, is an access rule rendered by access-engine. Holding
|
||||
that use-privilege does not confer the injected credential. The engine does
|
||||
not decide the permission and does not become a gate on the store.
|
||||
|
||||
An operator who is allowed to delegate may assign a task to another operator
|
||||
who is allowed to use an engine the delegator cannot use. The delegate uses
|
||||
the engine. The delegator does not gain that use-privilege or the injected
|
||||
credential. Engines stay stringent. Operators stay flexible. An operator's
|
||||
reliability does not relax an engine check.
|
||||
credential. Engines stay deterministic. Operators stay flexible and are
|
||||
expected to be reliable in the work they choose and assign.
|
||||
|
||||
Until ADR-015 is accepted, this section records the proposed doctrine. The
|
||||
security-layer standard is amended only after acceptance.
|
||||
|
|
@ -366,9 +370,11 @@ not cause another component to invent authority or silently substitute a
|
|||
broader credential.
|
||||
|
||||
The credential injected into an engine instance is that instance's
|
||||
encapsulated privilege, defined in §2.2. It authorizes the process toward its
|
||||
store for one scoped environment. It is not the operator's authority to use
|
||||
the instance, and it is not issued to the operator.
|
||||
encapsulated privilege, defined in §2.2. It enables that capability against
|
||||
its store for one scoped environment. Another engine may hold a different
|
||||
credential to the same store for a different capability. The injected
|
||||
credential is not the operator's authority to use the instance, and it is not
|
||||
issued to the operator.
|
||||
|
||||
## 10. MCP and tooling doctrine
|
||||
|
||||
|
|
@ -742,7 +748,7 @@ return path.
|
|||
| ADR-010 | Still meaningful — Autonomous mandate model. |
|
||||
| ADR-013 | Still meaningful — MCP authorization integration. |
|
||||
| ADR-014 | Still meaningful — policy self-modification protection. |
|
||||
| ADR-015 | Proposed — an engine is a processor; an operator's use-privilege is separate from the credentials injected into the instance. |
|
||||
| ADR-015 | Proposed — an engine enables one capability over Tooling; several engines may share a store; an operator's use-privilege is separate from the credentials injected into the instance. |
|
||||
|
||||
Future ADRs in Gate House decide doctrine and responsibility boundaries. They
|
||||
must not select an Engine's implementation technology or create a Gate House
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
**Repository:** gate-house
|
||||
**Status:** proposed
|
||||
**Date:** 2026-10-22
|
||||
**Revision:** 2026-10-22 — a store may serve several engines; an engine enables a capability and is not an access-control mechanism.
|
||||
|
||||
## Context
|
||||
|
||||
|
|
@ -21,28 +22,44 @@ separate use-privilege, "the operator uses the engine" collapses into "the
|
|||
operator receives the engine's credentials," or into the engine deciding for
|
||||
itself who may call it.
|
||||
|
||||
A first draft of this ADR also made each engine the only client of its store.
|
||||
That rule is withdrawn. One store can back several capabilities, and each
|
||||
capability can be an engine. Exclusive clientship would turn every engine into
|
||||
a gate on the records.
|
||||
|
||||
## Decision
|
||||
|
||||
An engine is a deterministic processor for one domain. It implements that
|
||||
domain from its canon. It does not hold the domain's records. Tooling holds
|
||||
the records. The engine owns the record type: the schema, the invariants, and
|
||||
the legal transitions. It is the only admitted client of its store.
|
||||
An engine is a tool of automation for one capability. It encapsulates the
|
||||
complexity of that capability in a consistent, often simpler interface than
|
||||
doing the work by hand. The same inputs yield the same result. That
|
||||
determinism is what reduces failure modes and what makes the work more
|
||||
reliable and more efficient.
|
||||
|
||||
An engine implements its capability from the domain canon. It does not hold
|
||||
the domain's records. Tooling holds the records. Several engines may use one
|
||||
store. Each engine provides a different capability over those records. Being
|
||||
an engine does not make a process the store's only client, and it does not
|
||||
make the engine an access-control mechanism. An engine enables the capability.
|
||||
Restricting who may act remains the domain of `access-engine`, not a property
|
||||
of engines in general.
|
||||
|
||||
The implementation has three manifestations of one library:
|
||||
|
||||
1. **Library.** The domain operations: validate, explain, plan, and compute
|
||||
the next state. A caller may use these pure operations without receiving a
|
||||
store credential.
|
||||
1. **Library.** The capability: validate, explain, plan, and compute the next
|
||||
state. A caller may use these operations without receiving a store
|
||||
credential.
|
||||
2. **CLI.** The library in a process. At start, the process is injected with
|
||||
the credential for one scoped environment. That credential lets the process
|
||||
read its inputs and write its outputs. It is not returned to the caller.
|
||||
reach the inputs and outputs of its capability. It is not returned to the
|
||||
caller.
|
||||
3. **Service.** The same process, kept running for a scoped environment that
|
||||
needs a standing processor. A service is not a second implementation and
|
||||
does not receive the credentials of any other environment.
|
||||
|
||||
`secrets-engine` is the reference shape. OpenBao is the store. The engine is
|
||||
the lifecycle processor. Build, test, and production are different scoped
|
||||
environments and different processes.
|
||||
`secrets-engine` is the reference shape. OpenBao is the store. The engine
|
||||
enables credential lifecycle as a reliable operation. Another engine may use
|
||||
OpenBao for a different capability. Build, test, and production are different
|
||||
scoped environments and different processes.
|
||||
|
||||
### Authentication and the operator
|
||||
|
||||
|
|
@ -53,16 +70,15 @@ not grant use of an engine.
|
|||
Two privileges stay distinct.
|
||||
|
||||
- The **encapsulated privilege** is the credential injected into one engine
|
||||
instance at start. It is how that process reads its inputs and writes its
|
||||
outputs. The operator does not possess it, see it, or reuse it outside the
|
||||
process.
|
||||
instance at start. It enables that instance to perform its capability. The
|
||||
operator does not possess it, see it, or reuse it outside the process.
|
||||
Holding it inside the process does not turn the engine into a restriction
|
||||
on the store.
|
||||
- The **use-privilege** is permission to start and call one named engine
|
||||
instance, or a named set of instances. `access-engine` renders that
|
||||
permission. The engine enforces the rendered result and does not decide it.
|
||||
A use-privilege is not a grant of the encapsulated credential, and it is not
|
||||
permission for every operation the domain can perform. The engine still
|
||||
applies its own deterministic rules to each call, including any decision
|
||||
record that domain requires.
|
||||
permission. The engine does not decide it and does not become the access
|
||||
control for its store. A use-privilege is not a grant of the encapsulated
|
||||
credential. It is permission to use the enabling interface.
|
||||
|
||||
Starting an instance and calling it both require a use-privilege for that
|
||||
instance. The operator who starts it is the operator under whose use the
|
||||
|
|
@ -76,22 +92,24 @@ uses the engine. The delegator does not gain the use-privilege and does not
|
|||
gain the encapsulated credential.
|
||||
|
||||
Delegation assigns work. It does not transfer either privilege. The delegate
|
||||
must already hold the use-privilege. The assignment cannot widen what the
|
||||
delegate is allowed to do, and it cannot authorize an operation the engine's
|
||||
own rules refuse. Engines stay deterministic and stringent. Operators stay
|
||||
flexible. Reliability of an operator is a Staff expectation. It does not relax
|
||||
an engine check.
|
||||
must already hold the use-privilege. Engines stay deterministic, so the
|
||||
enabled operation stays consistent. Operators stay flexible and are expected
|
||||
to be reliable in the work they choose and assign. That reliability is a
|
||||
Staff expectation. It is not a second restriction inside the engine.
|
||||
|
||||
## Consequences
|
||||
|
||||
- An engine intent that says the running service is the store of record is
|
||||
aligned later: the database, the vault, or the log is Tooling, and the
|
||||
engine remains the only admitted client and the owner of the record type.
|
||||
aligned later: the database, the vault, or the log is Tooling. The engine
|
||||
is a client of that store for its capability. Other engines may be clients
|
||||
of the same store for other capabilities.
|
||||
- `user-engine`, `tenant-engine`, `approval-engine`, and the access decision
|
||||
log are processors over records in Tooling. Approval consumption remains one
|
||||
transaction that the engine opens against its store. A user or tenant fact
|
||||
remains readable only through the engine.
|
||||
- `audit-core` appends and verifies. The tamper-evident store is Tooling.
|
||||
log are enabling processors over records in Tooling. Another engine may use
|
||||
the same records for a different capability. Approval consumption remains
|
||||
the approval capability's own transaction. It is not an exclusive lock on
|
||||
the store.
|
||||
- `audit-core` enables append and verification. The tamper-evident store is
|
||||
Tooling.
|
||||
- A Deployment exists when a scoped environment keeps the process running. A
|
||||
one-task environment manifests the same binary as a CLI. Absence of a
|
||||
Deployment does not make the engine incomplete.
|
||||
|
|
@ -105,18 +123,33 @@ an engine check.
|
|||
### The engine holds the records
|
||||
|
||||
Rejected because the layer cut already gives persistence to Tooling. Putting
|
||||
the store inside the engine makes the process the system of record and invites
|
||||
every other engine intent to do the same.
|
||||
the store inside the engine makes the process the system of record.
|
||||
|
||||
### Exactly one engine is the client of a store
|
||||
|
||||
Rejected because one store can back several capabilities. Each capability is
|
||||
an engine. Exclusive clientship would block a second engine from offering a
|
||||
different interface over the same records, and it would make the first engine
|
||||
a gate.
|
||||
|
||||
### The engine is the access control for its store
|
||||
|
||||
Rejected because an engine enables a capability. It encapsulates complexity
|
||||
so the operation is consistent, reliable, and efficient. Restricting who may
|
||||
act is `access-engine`'s domain. An injected credential does not create a
|
||||
second restriction mechanism.
|
||||
|
||||
### The operator receives the encapsulated credential
|
||||
|
||||
Rejected because the operator could then bypass the processor and call Tooling
|
||||
directly. That is the failure the use-privilege exists to prevent.
|
||||
Rejected because the operator would then perform the complex operation by
|
||||
hand. The engine exists so that work goes through the reliable interface.
|
||||
The use-privilege names who may invoke that interface. It does not hand over
|
||||
the store credential.
|
||||
|
||||
### The engine decides who may use it
|
||||
|
||||
Rejected because that decision is an access rule. An engine that renders it
|
||||
becomes a second policy decision point.
|
||||
takes on an access-control role this ADR withholds from engines in general.
|
||||
|
||||
### Delegation transfers the delegate's privileges to the delegator
|
||||
|
||||
|
|
@ -125,7 +158,7 @@ delegate already holds the use-privilege. The delegator remains without it.
|
|||
|
||||
### Library only, or service only
|
||||
|
||||
Rejected because the domain implementation, the process boundary, and the
|
||||
standing manifestation are one implementation. Collapsing them either gives
|
||||
callers the store credential inside a library, or forces a Deployment for a
|
||||
one-task environment.
|
||||
Rejected because the capability, the process boundary, and the standing
|
||||
manifestation are one implementation. Collapsing them either gives callers
|
||||
the store credential inside a library, or forces a Deployment for a one-task
|
||||
environment.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue