Least-privilege recertification pack

HelixOps production agents

HELIX-REV-2026-08-12 · Sample data · HelixOps · Generated for demonstration

1. Inventory summary

38 grants across 2 reviewers. Agents: Support Copilot, Sales Research Agent, Infra Operator, HR Onboarding Agent, Code Review Agent, Finance Close Agent.

AgentOwnerEnvGrants
Support CopilotMaya Chenproduction7
Sales Research AgentUnassignedproduction6
Infra OperatorDevOps sharedproduction7
HR Onboarding AgentPeople Opsproduction8
Code Review AgentPlatformproduction5
Finance Close AgentFinanceproduction5

2. Findings and evidence

R01 · Wildcard tools on web-fetch-mcpcriticalopen

A wildcard grant means this unowned production agent can invoke any current or future fetch tool, including ones that POST or follow redirects. That is broader than a sales-research job and cannot be recertified tool-by-tool.

  • sha256:7c1a9e2b44d0f18a · mcp.json: Sales Research Agent → web-fetch-mcp tools: ["fetch.*"]
R02 · Agent has no ownerhighassigned

Without a named owner, nobody can accept residual risk or reduce scopes. An unowned production agent will fail a customer questionnaire item on accountability.

  • sha256:12ab90c3e8f44b71 · csv import: agent=Sales Research Agent owner=null environment=production
R03 · Customer PII combined with outbound emailhighopen

The same production agent can read customer PII from Zendesk and Stripe and send email. That combination is a data-exfiltration path even if each grant looks reasonable on its own.

  • sha256:9d4e1a77c0b2aa15 · mcp.json: Support Copilot → Zendesk users.read, tickets.read (data class: Customer PII)
  • sha256:c8f03b91d6e44a20 · oauth console screenshot: Support Copilot → gmail.send on Google Workspace
R04 · Granted repo.write is unusedmediumopen

Write access on every repository is granted but not used. Observed traffic is comment and read only, so the write scope is residual privilege.

  • sha256:4b77e0c19a2d5f88 · repo scan: Code Review Agent GitHub OAuth scopes include repo (write on all repos)
  • sha256:a1cde59207bb34f0 · csv import: observed 30d: issues.comment=412, pull_requests.read=380, repo.write=0
R05 · Secrets access plus outbound webhookcriticalopen

This agent can read repository secrets and POST to an external webhook. Together those grants can move credentials off-box without a human in the loop.

  • sha256:e90b1c47d3aa6e12 · repo scan: Infra Operator → GitHub secrets.read / contents matching .env
  • sha256:55fa8d2c91e047b3 · mcp.json: Infra Operator → cloud console webhook.dispatch
R06 · Production label with staging Stripe keyshighopen

The inventory tags this agent as production while the Stripe grant is a test key. Reviewers cannot tell whether close data is real, and a later key swap would silently change the data class.

  • sha256:0c19d8e4a7b265f1 · csv import: Finance Close Agent environment=production
  • sha256:bb31f0a9c6d8472e · oauth console screenshot: Stripe connected account sk_test_… (staging) used by Finance Close Agent
R07 · Google admin scopes have no expiryhighaccepted

Directory admin scopes can create and suspend users. With no recertification date, the grant will outlive the onboarding project that justified it.

  • sha256:6e2d4c80b1f93a57 · oauth console screenshot: HR Onboarding Agent scopes=admin.directory.user, admin.directory.group; recertifyBy=null
R08 · Shared DevOps bot identityhighopen

A shared bot cannot be recertified by a person, and its GitHub and cloud grants outlive any individual on the DevOps rotation. Audit trails will not name who approved a change.

  • sha256:3a8f17c2e90d4b66 · csv import: Infra Operator owner="DevOps shared" identity=github-bot-helixops

3. Reviewer decisions

  • R01 · open

    Open — no decision recorded.

  • R02 · assigned · Jonah Hale · expires 2026-08-26

    No owner on a production agent. Assign Jonah Hale to name an owner and recertify web-fetch grants within 14 days.

  • R03 · open

    Open — no decision recorded.

  • R04 · open

    Open — no decision recorded.

  • R05 · open

    Open — no decision recorded.

  • R06 · open

    Open — no decision recorded.

  • R07 · accepted · People Ops · expires 2026-11-10

    People Ops needs directory admin during the current onboarding wave. Accept for 90 days, then drop admin scopes if the agent is only scheduling and announcing.

  • R08 · open

    Open — no decision recorded.

4. Remediation

  1. Replace web-fetch-mcp wildcard with an explicit tool allow-listUnassigned, due 2026-08-26
  2. Name an owner for Sales Research AgentJonah Hale, due 2026-08-26
  3. Separate PII read from gmail.send on Support CopilotMaya Chen, due 2026-09-09
  4. Drop unused GitHub repo write scope on Code Review AgentPlatform, due 2026-09-09
  5. Remove secrets.read and pin or disable webhook.dispatchDevOps shared, due 2026-08-19
  6. Correct Finance Close Agent environment or Stripe keyFinance, due 2026-08-26
  7. Set 90-day expiry on Google admin scopesPeople Ops, due 2026-11-10
  8. Replace shared DevOps bot with a named identityDevOps shared, due 2026-09-02

This pack does not modify external systems. HelixOps is sample data. Evidence hashes are of imported snippets, not live logs.