Same identity, different powers: running a live agent demo
3 min read
On 2 November I took part in an AWS webinar, Secure AI Agents on Amazon EKS: Sandboxing Sub-Agents with nono, alongside Carlos Santana and Luke Hinds. It went well, and I was really pleased with how curious people were: the questions and the excitement around nono were the best part.
This is a short write-up of what we showed and what it takes to run something like this live. The code is public in the demo repo.
The idea
Two AI agents share one GitHub identity and run in one Kata-isolated workload on Amazon EKS. nono, our agent runtime security layer, gives each agent only the capabilities its role needs. A developer agent fixes a prepared bug, runs the tests and opens a draft pull request. A reviewer agent reads it and leaves a comment. A person still approves and merges, under their own identity.
TLDR: a credential's permissions do not have to equal an agent's permissions. Both agents hold the same token, and they still can't do the same things.
Table 1: What each agent may do, with the same GitHub identity.
| Capability | Developer | Reviewer |
|---|---|---|
| Read issue, PR, diff and repository | Allow | Allow |
| Modify the worktree | Allow | Deny |
| Run tests | Allow | Allow |
| Push the designated branch | Allow | Deny |
| Open a draft PR | Allow | Deny |
| Post a PR comment | Not needed | Allow |
| Approve or merge | Deny | Deny |
| Read raw GitHub or model credentials | Deny | Deny |
| Unrestricted network access | Deny | Deny |
Kata isolates the workload from the EKS node, with a separate guest kernel. It does not isolate the developer from the reviewer, and it does not decide who may do what. That is nono's job, inside the guest.
Running it live
Perceiving a lot of the live demo through my SRE lens, as an operations problem, I couldn't help treating it as one:
- The repository is reset neatly before every run, through the demo's script.
- A readiness check runs to validate that things are good to go.
- The image can be frozen, so nothing changes between rehearsal and live run.
This was the shape of the output:
[DEVELOPER] nono profile: developer
00:05 ALLOW Read issue #1
00:09 ALLOW Modify code
00:10 ALLOW Run tests tests passed
00:14 ALLOW Open draft pull request
00:15 DENY Merge pull request command policy
[REVIEWER] nono profile: reviewer
00:31 ALLOW Post verdict comment
00:34 DENY Create or switch branch command policy
00:35 DENY Submit approval endpoint policy
00:36 DENY Merge pull request command policy
[VERIFICATION] checked by the launcher, not reported by the agents
01:02 PASS Pull request is open and unmerged
01:02 PASS Reviewer added 1 comment
01:08 PASS Credential files unreadableThe last block matters most. The launcher checks the result from outside, so the demo never relies on the agents saying the policy worked.
Why this matters
Agents are being handed real credentials, and the usual safeguard is hoping the agent listens to the prompt in the way we intended. The demo shows another way: enforce the boundary at runtime, around the agent, instead of trusting it from the inside. The same token can even sit behind two (or countless) different roles, and when an agent steps outside its role, the attempt is denied and logged.
That is what we are building nono for. It is open source, and the demo repo is a good place to try it.