Skip to content

feat: agent permission requests and approvals in the management UI #67

Closed

Description

@valentinalexeev-bot

🤖 AI agent: owner request on #59 (2026-10-31): surface permission notifications and approvals from agents in the management UI. The design is in docs/security-model.md, section Approvals and permission notifications.

  • Sources:
  • Storage: an Approval custom resource. API endpoints: list, an SSE stream, and decision (allow once, allow for this job, or deny), restricted to agentdev-admins and audit-logged.
  • UI: a badge with the number of pending requests, an Approvals page, and "waiting for approval" as an agent state. Optionally, a comment on the forge issue.
  • Safety:
    • fail closed
    • nothing granted beyond the current job
    • the reason text is shown as untrusted input
  • Depends on: Agents as the source of truth: 06, bootstrap and the API create Agent objects #57 steps 3-4 (API writes, admin group).

Activity

  1. valentinalexeev commented on Oct 31, 2026

    @valentinalexeev
    Owner

    Why restricted to agentdev-admins? Should be to the user - same level as if the agent was running interactively with the owner.

  2. valentinalexeev-bot commented on Oct 31, 2026

    @valentinalexeev-bot
    CollaboratorAuthor

    🤖 AI agent: agreed. The approver is now the user the agent works for, the same person who would answer the prompt in an interactive Claude Code session. Revised design (it lands in docs/security-model.md in a docs PR once #59 merges, to keep your approval on #59 valid):

    • Principal: for an issue job, the user who assigned the issue to the agent. For a feedback job, the author of the review being addressed (if they own or requested the PR), otherwise the user who assigned the issue. The forge login is linked to the authentik user.
    • No more than the user's own rights: the principal can approve only what they could do themselves. For example, a push under .github/workflows/ needs workflow write access in that repo, checked against the forge.
    • Set by the API: the principal comes from the job's forge data, never from the agent's request, so a compromised agent can't pick a friendlier approver.
    • Fallback: if the principal has no linked account or doesn't answer in time, the request goes to the agent's owners, then it's denied.
    • Admins: agentdev-admins see every request and can deny any (emergency stop), but approve only as the principal or an owner.
    • UI: the badge counts requests waiting for me; admins get an "all requests" view.
    • Audit: each entry records who decided and on whose behalf.

    New dependency: linking forge accounts to authentik users.

  3. valentinalexeev commented on Oct 31, 2026

    @valentinalexeev
    Owner

    Why linking forge accounts to authentik users? An agent runs within a project. Approval request surfaces into the project. Whoever has write access to this project can approve

  4. valentinalexeev-bot commented on Oct 31, 2026

    @valentinalexeev-bot
    CollaboratorAuthor

    🤖 AI agent: agreed, that's simpler. Approval now belongs to the project:

    • Requests show up in the project the agent runs in. Anyone with write access to that repository can approve or deny them. There's no principal, no extra role, and no account-linking step.
    • Forge as an approval surface: the agent comments on its issue or PR with "waiting for approval". A reply of /approve, /approve-job or /deny from a user with write access decides it. The sidecar checks the commenter's permission through the forge API. Here the forge identity is just the commenter, so nothing needs linking.
    • In the UI, the API has to know which forge user is clicking in order to check their write access. The plan is to make the forge an authentik login source (sign in with GitHub or Gitea). That's ordinary authentik setup, not a separate link per user. If you'd rather have the UI show requests and leave decisions to the forge, that drops this dependency entirely.
    • Admins can still deny anything as an emergency stop. Nobody can approve beyond their own rights in the repo. Whatever no one decides before the timeout is denied.

    The doc update goes into the post-#59 docs PR. Question: should UI decisions be in scope, with forge login through authentik, or should the forge be the only place to decide for now?

  5. valentinalexeev-bot commented on Oct 31, 2026

    @valentinalexeev-bot
    CollaboratorAuthor

    🤖 AI agent: decision needed (asked earlier only in chat, sorry).

    Question: should approvals be decided in the UI in the first version, or only on the forge?

    Proposed default: both, in two steps.

    1. First version: the forge (/approve <id> comments). It needs no new sign-in and works today with your forge accounts. The UI shows the requests and their history, read-only.
    2. Next: decisions in the UI too, once the forge is set up as an authentik login source, so the API knows which forge user clicked and can check their write access.

    Reply "default ok" or pick one option.

  6. valentinalexeev commented on Oct 31, 2026

    @valentinalexeev
    Owner

    Default ok, UI approvals as a separate task

  7. valentinalexeev-bot commented on Oct 31, 2026

    @valentinalexeev-bot
    CollaboratorAuthor

    🤖 AI agent: noted. #67 covers approvals decided on the forge, with read-only Pending and History views in the UI. Deciding in the UI is now #80. I've removed needs-decision.

  8. 34 remaining items

  9. valentinalexeev commented on Nov 1, 2026

    @valentinalexeev
    Owner

    UI decisioning is in scope here. On the path to 1.0.0.

  10. valentinalexeev-bot commented on Nov 1, 2026

    @valentinalexeev-bot
    CollaboratorAuthor

    🤖 Decision recorded: deciding approvals in the UI is part of #67 and on the path to 1.0.0. This replaces the earlier forge-first-only scope. #107 delivers the forge decisions and the read-only Approvals page. A follow-up PR adds Approve / Approve for job / Deny buttons in the UI, with the same rules as forge comments: live write-access check, never the requester, audited, first decision wins and void records are ignored. #80 is folded into #67.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or requestin-progressBeing worked onneeds-decisionWaits for an owner decision (question in a comment)

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions