Conversation
How bravebot gets capabilities that need a secret, email first, without ever holding one. Extends Brave Vault rather than adding a second broker: its agent-access plan already states the principles, so the work is hardening its storage and adding a service-token item type and a perform action. Six phases, 34 tests, and three limits stated rather than glossed: the approval boundary does not hold against a same-uid attacker, encryption at rest covers a stolen disk only, and none of it retrofits credentials already on the machine.
AliShahin
force-pushed
the
credentials-design
branch
from
September 10, 2026 22:17
03ddfc8 to
76fc1cf
Compare
2 tasks
…the capability inventory The ladder moved out to the spec draft and left five references behind with nothing to resolve against. Restates the four rungs compactly here. The per-capability inventory went with it, so nothing said what source control, cloud, payments or protocol servers actually need, or why a card number is the worst-designed credential an agent could hold.
…c's tiers Renames credentials.md to credential-brokering.md. It pairs with the discovery design and says what the document decides rather than restating its subject. The rung ladder becomes the four named tiers. Two numbering schemes for one ladder put "rung 1 is best" beside "gate 1 is the first failure", pointing in opposite directions. The two paths follow: the broker performing an action whole is Performed rather than Delegated, because substitution reaches Delegated too, and naming one path after the tier implied the other did not. Binds the vocabulary the rest of the work uses: the broker is the authority and the performer. Neither word appeared in this document before. Smaller corrections. The tier table's subject is the account, not the agent, which is the boundary the adversary model turns on. Each row of what this does not cover says which of the two conditions it fails. The capability inventory says up front that only email is in scope for the phases below. Phases 5 and 6 are marked as carrying no tests.
Before the first turn reads a directory, scan it, show what is there, and let the person answer once. The detector is built in Brave guardrails, which already intercepts a command's output and needs a checker that matches rather than one that judges. The rules are vendored from betterleaks as a pinned file, because patterns change weekly and engines do not. Eight phases and 30 tests. Three limits stated rather than glossed: a clean result is not a clearance, a denied path is a tool-boundary block and not confinement, and removing a finding does not end the credential.
Where credentials come from, which of them may be held at all, and what a tier binds: four tiers, three gates, and a walk that records which of the gate's conditions failed and whether the counterparty refused or nobody attempted it. Separate from labels.md because the typed credential never becomes a labelled value, so the flow control has no opinion about one, which is also the answer to why the agent is not simply given the secret. Twenty-five clauses. The safehouse comparison is what carries that answer: three of the properties its credential gate rests on hold here too, and the four that fail all reduce to an open tool surface over a local tree. Three limits stated rather than glossed: substitution matches a performer on custody and not on authority, detection sizes a brief window without setting a tier, and nothing here is implemented.
AliShahin
force-pushed
the
credentials-design
branch
from
September 16, 2026 12:32
26fce0e to
acfd8ef
Compare
The two paths were described as equivalent because the agent holds nothing in both. That is true of custody and not of authority: the egress boundary matches on host, so it bounds where a request goes and never which operation it asks for. A performer exposes one action; a substituted credential exposes everything the far end accepts at that destination. Which gives the rule that decides between them. Substitution is safe where the issuer bounds the dimension the boundary cannot see. `git push` passes, because the repository is in the path and a GitHub App token is minted for one of them. Email fails, because no provider will scope a token to a recipient, so only something that reads the envelope can bound one. Adds a diagram for setup and one per message, so the one consent and the one approval are visible, and a worked example of the substituted path, which phase 4 did not have. Writing it out found two things the phase has to settle: a push's credential sits inside a base64 value rather than in a header, which the position rule does not cover, and the boundary has to terminate the push's TLS to reach it at all. Tier rows, lifetimes and two rows of what this does not cover now agree with the spec rather than restating it loosely. The architecture diagram no longer draws a child's proxy as a boundary the text calls advice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three documents: one spec that says what must be true, and two designs that
answer to it.
credential-protection.md (
CRED): where credentials come from, which of themmay be held at all, and what a tier binds. Four tiers and three gates, walked
from the top, with each drop recording which condition failed and whether the
counterparty refused or nobody attempted it. It sits apart from labels.md
because the typed credential never becomes a labelled value, so the flow
control has no opinion about one. Twenty-five clauses.
credential-brokering.md: how bravebot gets capabilities that need a secret,
email first, without ever holding one. Extends Brave Vault rather than adding
a second broker. Six phases, 34 tests.
credential-discovery.md: how the credentials already in a working tree are
found before the first turn reads it, shown to the person, and given a
disposition. Built in Brave guardrails, with a rule set vendored from
betterleaks. Eight phases, 30 tests.
The designs divide on capability rather than location: discovery answers
whatever is in the tree, brokering whatever the authority can hold and act
for. The spec is where both stop, since it fixes the tiers they quote and the
gates that decide them.
The argument the spec adds is why the agent is not simply given the secret,
and it is made against safehouse rather than in the abstract. Three of the
properties safehouse's credential gate rests on hold in bravebot too: a label
cannot carry a secret, call parameters are decided from trusted data, and the
key travels in a header the model never sees. The four that fail all reduce to
one thing, which is an open tool surface over a local working tree rather than
typed calls over fetched data.
run's parameter is a command line, so there isno signature to scope a credential to; the content is the person's tree, which
is itself where
.envand*.pemlive. So the boundary has to sit outsidethis process, which is what the brokering design builds.
Limits stated rather than glossed: substitution matches a performer on custody
and not on authority, since the boundary bounds where a request goes and not
which operation it asks for; detection sizes a brief window without setting a
tier; and nothing here is implemented, so twenty-four clauses are
verified-by: noneandmake check-specreports them as warnings.Three places where the code already disagrees with the spec are noted rather
than fixed here, since spec conformance runs in one direction:
SecretderivesPartialEq, giving an equality oracle over a credential; the subscriptionbatch is a plain
Stringunder#[derive(Debug)]; and under Bedrock what thisagent authenticates with is the machine's own cloud credentials, which RUN-12
deliberately leaves in a subprocess's environment.