Inspiration
Imagine giving an AI Agent a simple task: summarize a confidential document.
Now imagine that same Agent is part of a larger multi-Agent workflow. A Lead Agent delegates work to several specialists. One specialist needs the document. Another does not.
Who decides which Agent actually gets to see it?
As AI Agents move from answering questions to taking actions on our behalf, they are being given access to files, tools, APIs, and increasingly, other Agents.
That creates a fundamental security problem:
A human may be trusted with a resource. That does not mean every Agent acting on that human's behalf should inherit the same authority.
At SmallPotato, we did not want to solve this by adding another prompt telling the Agent what it should or should not access.
A prompt is guidance. We wanted enforcement.
So we started with one principle:
Autonomy should never mean unlimited authority.
That became PotatoGuard: a security boundary outside the model that decides what an Agent is actually allowed to access before protected data ever reaches its Runtime.
What it does
PotatoGuard is the security boundary for autonomous AI Agents.
The core idea is simple:
Human identity ≠ Agent identity
A human can own an Agent without giving that Agent all of the human's permissions.
Every Agent receives its own server-generated principal identity, and protected-resource access is delegated explicitly to that Agent through narrowly scoped, expiring, and revocable authority.
Conceptually:
Agent Principal
+
Resource
+
Action
+
Task Context
+
Expiry / Revocation State
↓
PotatoGuard
↓
ALLOW or DENY
The important part is when that decision happens.
PotatoGuard authorizes the request before the protected resource enters the Agent Runtime.
On DENY:
Protected request
↓
PotatoGuard
↓
DENY
↓
No protected mount
No protected Agent Run
Audit evidence recorded
On ALLOW:
Protected request
↓
PotatoGuard
↓
ALLOW
↓
Only the approved resource
↓
Read-only Runtime mount
↓
Real Agent execution
This same model works for both single-Agent execution and multi-Agent Team Tasks.
In a Team Task, the Lead coordinates the workflow, but coordination does not imply authority.
Lead / Orchestrator
|
+-----------+-----------+
| | |
Specialist A Specialist B Specialist C
| | |
Principal A Principal B Principal C
| | |
+-----------+-----------+
|
PotatoGuard
|
ALLOW / DENY
Each specialist is independently authorized.
There is no blanket "Team Task permission" that silently gives every Agent access to every resource.
If a specialist lacks the required authority, the task can pause for human approval. Once approved, the specialist can resume with the newly delegated access.
Our guiding principle is:
The Agent decides what it wants to do. PotatoGuard decides what it is allowed to access.
How we built it
We built PotatoGuard directly into the execution path of the Agent Launchpad as trusted server-side middleware between the control plane, protected resources, and the Agent Runtime.
The architecture is built around two trust boundaries.
Trust Boundary 1: Browser → Control Plane
The browser expresses user intent, but it is not trusted to tell PotatoGuard who owns an Agent or resource.
Human identity is resolved from a server-managed session, and browser-controlled ownership fields are rejected rather than trusted for authorization.
Each Agent then receives a separate server-generated principalId.
This gives us two distinct identities:
Human
|
| owns
v
Agent
|
| has independent
v
Agent Principal
Ownership and authority are deliberately different concepts.
Trust Boundary 2: Control Plane → Agent Runtime
This is the most important boundary in PotatoGuard.
Before a protected resource is mounted, the backend evaluates:
- the authenticated human;
- Agent ownership;
- the Agent's principal;
- resource ownership;
- explicit cross-user sharing;
- requested action;
- task context;
- capability state;
- expiry; and
- revocation.
Only after that check returns ALLOW can the approved protected-resource path cross into the Runtime.
Browser
|
v
Server Session
|
v
Human + Agent Identity
|
v
Scoped Authority
|
v
================================
POTATOGUARD
ENFORCEMENT POINT
================================
/ \
DENY ALLOW
| |
no mount approved
no Run resource only
|
v
Agent Runtime
This placement matters because the UI, the Agent, and the multi-Agent orchestrator can all request access, but none of them can grant it to themselves.
Least-privilege delegation
Protected-resource authority is represented as temporary capabilities rather than standing human authority.
Capabilities can:
- be scoped to a particular Agent;
- target a particular resource and action;
- expire automatically;
- be revoked immediately;
- be bound to Team Task context; and
- support explicit owner-controlled cross-user sharing.
Runtime isolation
For an authorized protected turn, only the approved resource is mounted into the disposable Agent Runtime, and that protected mount is read-only.
Ordinary Agent workspace access remains separate from the protected-resource vault.
Auditability
Every important authorization decision produces attributable audit evidence.
A receipt can capture:
Human
Agent Principal
Resource
Action
ALLOW / DENY
Reason
Timestamp
Run / Team Task Context
Previous Receipt Hash
Current Receipt Hash
Receipts are hash-linked so that modifying stored audit evidence breaks chain verification.
This means PotatoGuard does not only enforce a decision.
It leaves evidence of who requested what, which Agent was involved, why the decision was made, and which execution it belonged to.
Our full trust-boundary design is documented in the PotatoGuard architecture.
How we know it works
For security middleware, an ALLOW demo is not enough.
The important question is whether the system behaves correctly when authority is missing, stale, revoked, foreign, or manipulated.
So our automated verification targets the authorization boundary itself rather than relying on the UI.
| Scenario | Expected PotatoGuard behavior |
|---|---|
| Valid scoped authority | ALLOW and mount only the approved resource |
| Missing grant | DENY before protected Runtime execution |
| Expired grant | DENY |
| Revoked grant | DENY immediately on the next check |
| Foreign Agent | Reject access |
| Foreign resource without explicit share | DENY |
| Revoked cross-user share | DENY |
| Deleted protected resource | Clean dependent authority and reject access |
| Valid Team Task specialist | Authorize that specialist independently |
| Unauthorized Team Task specialist | Pause instead of inheriting Team authority |
| Human approves blocked specialist | Resume with newly delegated authority |
| Stored receipt modified | Audit-chain verification fails |
One of the most important assertions in our test suite is not simply:
DENY returned
It is:
DENY returned
+
Specialist Agents was never invoked
That distinction matters.
A security layer that says DENY after giving the protected data to the Agent has already failed.
PotatoGuard's boundary is designed so that a denied protected request stops before the protected Agent execution begins.
Challenges we ran into
The hardest part of PotatoGuard was not writing an if statement that returned ALLOW or DENY.
It was deciding what must be trusted, where authority should live, and exactly where enforcement has to happen.
The frontend cannot be the security boundary
Our first principle was that hiding a resource or disabling a button in the UI does not constitute authorization.
A caller can bypass the frontend.
That meant ownership and permission checks had to live in the trusted server-side path.
The model cannot be the security boundary either
We could tell an Agent:
"Only access resources you are authorized to use."
But the Agent is precisely the component whose authority we are trying to constrain.
An Agent can be manipulated by untrusted context, misunderstand instructions, or simply make the wrong decision.
So the model can request an action.
It cannot authorize itself to perform that action.
Human identity and Agent identity had to be separated
This created a deeper design question.
Suppose Alice owns six Agents and Alice can access a financial report.
Should all six Agents automatically receive that access?
We decided the answer must be no.
Alice can access Resource X
does NOT imply
Every Agent owned by Alice can access Resource X
Authority has to be delegated to the particular Agent that needs it.
That separation became the foundation of PotatoGuard.
Multi-Agent workflows exposed the danger of inherited authority
Team Tasks made the problem even more interesting.
A Lead Agent may coordinate several specialists, but giving the entire task a single permission would allow authority to spread implicitly across the team.
We instead kept the authorization context attached to the individual specialist principal.
The Lead can decide:
"Specialist B should perform this step."
But PotatoGuard separately decides:
"Is Specialist B allowed to access the resource required for this step?"
Coordination and authorization remain separate responsibilities.
Revocation had to mean something
A permission system is not meaningfully revocable if revoked authority remains usable for the rest of a workflow.
PotatoGuard therefore checks capability state again when protected access is requested.
A revoked or expired capability is denied on the next authorization check.
Audit evidence must not become another data leak
We wanted detailed evidence of security decisions without placing protected document contents into the audit export.
That forced us to distinguish between decision metadata and protected data.
We record enough information to reconstruct the authorization decision while keeping protected document contents outside the exported audit trail.
We had to be precise about what PotatoGuard does not solve
A read-only mount prevents an Agent from modifying that protected mount.
It does not, by itself, mean an authorized Agent can never transmit information it has legitimately been allowed to read.
That distinction matters.
PotatoGuard is a pre-Runtime authorization boundary, not a claim that our hackathon container is a fully hardened production sandbox.
Being explicit about that boundary made the design stronger because we could focus on proving the property we actually built:
A protected vault resource does not enter the Agent Runtime until trusted server-side authorization returns
ALLOW.
Accomplishments that we're proud of
The part we are most proud of is that PotatoGuard turns Agent authorization from an instruction into an enforced system property.
We separated ownership from authority
A human can own an Agent without the Agent automatically inheriting the human's protected-resource access.
Every Agent has its own principal.
We enforce before Runtime access
A denied protected request does not merely display an error after execution.
It stops before the protected resource is mounted and before the protected Agent Run proceeds.
We built one authorization model for single and multi-Agent systems
The same security boundary handles:
Single Agent
|
v
PotatoGuard
and:
Multi-Agent Team
|
Individual Specialist Principal
|
v
PotatoGuard
We did not create a weaker security model just because multiple Agents were involved.
We made authority temporary
Access can expire.
Access can be revoked.
Cross-user sharing can be granted explicitly and withdrawn.
Team Task authority can be tied to the lifecycle of the task.
We preserved human control
When a specialist does not have the authority required for a Team Task, PotatoGuard can pause the workflow for human approval rather than silently granting access or permanently killing the task.
We made decisions attributable
Authorization evidence links the human, Agent principal, resource, decision, reason, and execution context.
The receipt chain can also detect modification of previously stored evidence.
So when something happens, we can ask more than:
"Did the Agent run?"
We can ask:
Which human delegated authority, which Agent exercised it, which resource crossed the boundary, why was it allowed, and can we still trust the record of that decision?
What we learned
The biggest lesson we learned is that Agent authentication and Agent authorization are not the same problem.
Authentication can answer:
Who is the human?
But an autonomous system also needs to answer:
Which Agent is acting?
What authority was delegated to that Agent?
For which resource and action?
In which task context?
Is that authority still valid right now?
That changed the way we thought about Agent infrastructure.
We also learned that where you enforce a policy matters as much as the policy itself.
A rule in a prompt is advisory.
A disabled UI control is bypassable.
A permission checked after the resource enters the Runtime is too late.
The meaningful enforcement point is the trusted boundary before protected data crosses into Agent execution.
Multi-Agent workflows taught us another important lesson:
Coordination does not imply authorization.
An orchestrator may decide who should perform work. It should not automatically determine what every specialist is allowed to access.
Finally, we learned that good security engineering also means being precise about your claims.
PotatoGuard is not a production IAM platform or a hardened multi-tenant sandbox.
It is a hackathon-scale proof of concept demonstrating something narrower and, we believe, fundamental:
Autonomous Agents should receive explicit, least-privilege authority of their own rather than silently inheriting the authority of the humans or workflows that created them.
What's next for PotatoGuard
PotatoGuard currently demonstrates this model locally, but the same architecture can extend much further.
Our next steps include:
- enterprise identity through OIDC / SSO, connecting Agent delegation to organizational identity;
- transactional authorization storage for durable and concurrent policy state;
- externally backed and cryptographically signed audit evidence;
- managed secret storage;
- stronger per-tenant Runtime isolation using hardened sandboxing;
- network-aware policy controls for authorized Agents after data enters the Runtime;
- richer capability conditions, including budgets, environments, risk levels, and tool permissions;
- monitoring and alerting for unusual Agent-resource authorization patterns; and
- policy administration for large multi-Agent organizations.
As Agents become more capable, organizations will need more than a way to authenticate humans.
They will need a way to delegate authority to autonomous software without surrendering control over that authority.
That is the role we want PotatoGuard to fill.
Give Agents the autonomy to act — without giving them the keys to everything.
And after spending the hackathon thinking deeply about Agent infrastructure, security boundaries, and multi-Agent systems, we would love the opportunity to keep building problems like these at TikTok.
Built With
- agent-security
- ai-agents
- audit-logging
- authorization-middleware
- capability-based-security
- codex-cli
- docker
- docker-compose
- fastify
- identity-and-access-management
- least-privilege
- multi-agent-systems
- node.js
- react
- rest-api
- runtime-security
- tamper-evident-logs
- terraform
- typescript
- vite
- vitest
- volcengine-ark
- volcengine-ecs
- zod
Log in or sign up for Devpost to join the conversation.