Security veto is a role, not a vibe
Scheduled7 min read By NT²
Agents can draft patches and greenlights. They cannot own the decision that a vault still refuses password escrow, extractable keys, or a “helpful” recovery desk. Security veto is a role with authority—not a mood in chat.
Security veto is a role, not a vibe
Claim: speed without a named blocker is not a secure process
AI coding agents are excellent at proposing the next diff. They are also excellent at sounding sure.
That combination is dangerous for a zero-knowledge vault. A fluent agent can “fix” unlock by uploading salt “just for recovery,” make a vault AES key extractable “so tests are easier,” add a forgot-password email path because every SaaS tutorial has one, or pull a crypto library with a postinstall script that nobody read. The patch may even pass typecheck. The threat model does not care.
So the claim for this installment is operational, not motivational:
In the agent loop, security veto is an explicit role with authority to block merge and release. Automated gates are evidence. A human remains accountable for crypto and security decisions.
This is the deepen after How one person builds and operates NT² Vault with AI agents and Specs before agents write code. Specs bound what may be built. The security veto bounds whether a change that touches secrets is allowed to ship—even when the agent is confident and the checklist looks green.
Constraint: agents optimize for done; vaults optimize for refusal
Three pressures make “the CI is green, ship it” fail when the product is a vault.
Training priors prefer helpful servers. Models have seen millions of lines that escrow passwords, store KDF material in the cloud, and treat support desks as recovery oracles. Without a hard blocker, “helpful” is the default completion.
Security theater looks like diligence. Adding a dependency scan badge, a vague “security considerations” paragraph, or a self-review that says “looks fine” is easy. None of that substitutes for walking unlock, wrong password, lock, and backup on a change that touched those paths.
One-person throughput amplifies silent authority transfer. When the same human asks an agent to implement, the agent proposes merge text, and nobody else reviews, it is tempting to treat the agent’s confidence as a co-signer. It is not. Accountability does not transfer to a model.
The constraint is therefore sharp: you cannot outsource the veto to vibes, model self-assessment, or “we’ll harden it later.” Later never comes for a shipped password oracle.
Design: gates as evidence, veto as authority
We separate three things that teams often collapse into one word—“security.”
| Layer | What it is | What it is not |
|---|---|---|
| Invariants | Short, always-loaded rules: master password never leaves the device; keys non-extractable; salt local; session keys die on lock/refresh; cloud stays blind | Adjectives (“be careful,” “secure by default”) |
| Automated gates | Unit tests, typecheck, coverage floors on crypto packages, production dependency audit, static rules (no raw HTML sinks, frozen lockfile) | Proof that a human reviewed threat impact |
| Security veto | A named human role that may block merge/release on unlock, crypto, backup, sync auth, and supply-chain surprises | A chat mood, a rubber stamp, or the implementer’s self-approval |
The loop looks like this:
flowchart LR
S[Spec slice approved]
I[Agent implements]
G[Automated gates]
R[Read-only security review]
V{Human veto?}
M[Merge / release]
S --> I --> G --> R --> V
V -->|block| I
V -->|accept| M
Invariants live in the project constitution the agent must load every session. They are executable in spirit: each maps to review checks, tests where possible, and a walkthrough when the change touches unlock or key handling. Examples that show up again and again in public product choices: KDF salt stays on the device, we cannot reset your master password, and crypto keys must not survive refresh.
Automated gates run on commit, push, and CI. They catch the mechanical failures—broken types, missing coverage on shared crypto packages, high-severity production dependency issues, forbidden HTML sinks. They are necessary. They are not sufficient for “does this PR recreate a server-side password oracle?”
The veto is read-first when possible. A security reviewer that immediately rewrites the patch and then approves its own rewrite has collapsed review into implementation. Prefer: analyze threats and invariant violations, report blockers, leave the implementer (human or agent under human direction) to fix. The human who owns the product still signs the accept/block decision.
What triggers the full gate
Not every documentation typo needs a crypto walkthrough. Risk escalates the gate:
- Touch unlock, key derivation, key wrap, backup export/import, or cloud auth → full security path: tests for pure logic, integration where APIs changed, and a manual walkthrough of unlock, wrong password, lock, and backup.
- New dependency → justification: purpose, maintainer trust, absence of suspicious install scripts; crypto/identity stacks do not arrive as drive-bys.
- Shared crypto or event packages → harder coverage floors than the rest of the tree.
- Dependabot and production audits → human merge judgment; critical production issues get a short clock, not a shrug.
CI can fail closed on audit and static analysis. It still cannot feel whether “forgot password” snuck in as a support nicety.
Accountability stays with the human
Agents may analyze and recommend a veto. They may draft the threat note. They do not silently convert that recommendation into merge authority, and they do not deploy because the command is in the README. The operating model from the lifecycle essay still holds: produce decisions for review; do not infer consent.
For NT², that also means vault plaintext never becomes prompt fodder for a coding assistant, and customer-facing replies that touch accounts stay human-reviewed. The security veto is not only about code; it is about which data planes an AI is allowed to see.
Trade-off: slower merges, fewer irreversible crypto mistakes
Putting a named veto in the loop costs time. A one-person shop feels that cost immediately: you are both the implementer’s sponsor and the reviewer who must say no.
What we give up:
- Merge-on-green theater — treating CI as the only security reviewer.
- Agent self-sign-off — “I reviewed my own diff and it looks secure.”
- Helpful recovery features that recreate escrow, oracles, or extractable keys because a tutorial said users expect them.
- Drive-by crypto libraries pulled because an agent “found a package that does DID everything.”
What we gain:
- A durable refusal trail — when something is blocked, the reason maps to an invariant, not a vibe.
- Separation of evidence and authority — gates prove mechanical health; humans accept residual risk.
- Compatible agent speed — agents still draft and fix; they do not get to redefine the threat model mid-PR.
- Product honesty — public claims like “no password reset” and “salt stays on device” stay true because process refuses the opposite.
The expensive failure mode is not “spent an hour on a security walkthrough.” It is “shipped a convenience that teaches every future agent the constitution is optional.”
What we refuse
We refuse security as a mood. “Be careful with crypto” is not a gate. Named invariants, automated evidence, and a human veto are.
We refuse treating green CI as merge authority for unlock and key paths. Tests and audits are mandatory evidence. They do not replace walking the session: unlock, wrong password, lock, export.
We refuse extractable vault keys “for debugging.” If a key can be exported into JavaScript, XSS has a theft path. Tests use other seams.
We refuse cloud-side unlock oracles disguised as recovery: uploaded salt, server-held verifiers, or support tools that decrypt user data. The product cannot reset a forgotten master password—and the process must not invent a back door that contradicts that promise.
We refuse agent merge or deploy without explicit human authorization. Knowing the command is not the same as holding the authority.
We refuse self-approving security review. The implementer may fix; the veto role stays read-oriented and accountable to a human owner.
We refuse new crypto or identity stacks without an explicit product decision. Selective standards are a design choice, not a shopping list for the nearest npm package.
We refuse feeding vault plaintext into AI services. Coding and ops assistants work on source, tests, and minimized operational context—not decrypted user payloads.
These refusals are how agent throughput stays compatible with a vault whose edge is blind and whose unlock material never becomes someone else’s problem to “help” with.
Roles that outlast the model
Security veto is not a personality trait of a careful engineer. It is a role in the loop: invariants load every session, gates produce evidence, a human may block, and accountability does not transfer to the model.
The authority table and release discipline live in How one person builds and operates NT² Vault with AI agents. The contract that keeps agents from inventing the wrong product lives in Specs before agents write code. The product-side refusals this process protects are essays like no password reset by design, KDF salt stays on the device, and crypto keys must not survive refresh.
If you want a vault built so process and cryptography refuse the same shortcuts—try NT² Vault or read more at nt2.me.
Last updated 2026-10-22
Related stories
- Shared crypto packages get a 100% coverage floor
8 min read
- Specs before agents write code
7 min read
- How one person builds and operates NT² Vault with AI agents
10 min read