Agents · Access management

We stopped making engineers wait for access

Role management via chat: an agent I built that makes non-production access self-serve, audited, and locked out of production.

  • AI agents
  • Slack
  • Access management
  • Least privilege
  • In use

The problem

People across the firm need roles all the time, to reproduce a bug or demo a feature, and they can't grant one to themselves. Only the platform team can. So they raised a request with the platform team's on-call, or with someone they knew on that team, and waited, often for a role that turned out to be the wrong one, or for the first of several personas they needed.

The Mr Bean waiting meme: four panels of Mr Bean in a field of yellow flowers, standing with his hands on his hips, then checking his watch, then sitting by the roadside, and finally lying flat on the verge
Waiting for the right roles.

Both sides lost: the teams asking lost time waiting, and the on-call spent theirs on repetitive, low-risk requests instead of focusing on their core responsibilities.

For non-production environments, none of that queueing should be necessary. Nothing there touches a customer; you just want to get your work done. That is why I built a skill for our internal AI assistant that grants non-production roles from a plain-language request in Slack, with no queue.

Roles and permissions, from zero

  • Tenant. One customer's own space on a shared platform, with its own data, users and settings.
  • Permission. A single action, such as viewing a report or inviting a user.
  • Role. A named bundle of permissions, such as "admin" or "view-only".
  • Granting. Giving a user a role in a specific product and tenant.
Permission (made-up example)View-onlyMarketing userAdmin
View reportsYesYesYes
Create and edit campaignsNoYesYes
Invite users and assign rolesNoNoYes
The confused math lady meme: a woman squinting in confusion as equations and geometry diagrams float around her
So many roles and permissions. Which one should I get?

What already existed

I didn't start from scratch. Three things were already in place:

  • Orca. Our internal AI assistant, built and maintained by another team. It already lived in Slack, and it spins up an AI coding agent to do the work and manages that agent's lifecycle.
  • Skills. Orca's way of learning new jobs. A team registers a skill with a description of the requests it should handle, and the agent picks it up when a request matches.
  • Our app and identity provider. The systems where users and their roles actually live, which only the platform team's tooling could change.

What was missing was a way for anyone to get a role without going through the platform team. That is the part I built: a skill for my team's use case, added to Orca, and the plumbing behind it.

The idea: just ask

The agent handles these requests in plain language in Slack. There is no form, no ticket and no new tool to learn, and you can ask for yourself or for a teammate. These are the kinds of requests people made during the trial:

  • "Give a teammate admin access to one of our apps for a tenant."
  • "Make a user a marketing user for workflows."
  • "Give a user view-only access."
  • "For this environment, what are my roles for this tenant?"

What it can do

CapabilityWhat it does
RolesSets, changes or removes a user's role in a product, and maps loose wording like "admin" or "view only" to the tenant's real role.
InvitesInvites a new user with a role, or re-sends an expired invite, once you confirm.
Enabling usersReactivates a disabled user without changing their role.
Staff accessGrants internal staff access, or time-boxed edit access within a tenant.
Look-upsShows which roles someone holds, which roles a tenant offers, and licence totals and usage.
Bulk requestsHandles "view-only for all apps" by picking the lowest-privilege role in each app the tenant has, then lists exactly what it assigned.
Self-descriptionExplains what it can do when you aren't sure what to ask.

How a request flows

An access request, end to end You ask Orca in Slack in plain language. Orca matches the request to the access skill and runs its commands. The skill's clients ask the internal services for the tenant and its roles, map your wording to a real role and validate the request. If anything is unclear, Orca asks you one question in Slack and you answer. The skill then asks the internal services, which accept only non-production calls, to apply the change; they update the role in both the app and the identity provider and roll back if the sync fails. The skill re-reads the user's state, and Orca reports the result for each user in Slack. Youin Slack OrcaAI agent Access skillclients Internal servicesnon-production only App and identityprovider 1 · Ask in plain language 2 · Match the access skill 3 · Run skill commands 4 · Find tenant, list roles tenant and its roles 5 · Map wording to a role, validate IF UNCLEAR 6 · Ask one question answer in Slack 7 · Apply change production calls rejected 8 · Update role in both rolled back if sync fails 9 · Re-read user's state roles held now 10 · Report result per user
One request, end to end. Dashed arrows are replies.

A clear request just runs. The agent asks one short question only when something is missing or ambiguous, and it never guesses a role or an email address. If you don't name an environment, it uses the safer non-production one and tells you so.

Designing for safety first

Letting an AI agent change access sounds risky, so the guardrails were the main design work:

GuardrailWhat it means
Non-production onlyDeclines production requests, and the services behind it reject production calls by design, so it can't reach production even by mistake.
No guessingNever infers an email address from a name or picks between ambiguous roles; it asks instead.
Allow-listed domainsInvites or changes only users on approved email domains.
No lock-outsBlocks any removal that would leave a user with no role.
Least privilegeDeclines the highest-privilege role and offers the next level down, and it hands removal of staff access to IT or the platform team.
Honest reportingReports an invite as "invited, must accept", never as "access granted", and re-reads the user's state after every change to report what they hold now.
No blind retriesNever retries a write automatically, and it serialises concurrent changes to the same tenant.
Audit trailLogs every change with the requester's identity.
Protected attributesCannot set sensitive flags through the role and invite paths.

How it's built

What the skill is made of

PartWhat it does
TriggerMatches any request for a role change or access, so the agent picks the skill up from plain language.
SKILL.mdLists every capability the skill exposes, as commands the coding agent can run.
Access.mdWrites down the nuances of every use case, so the agent never has to guess them.
Deterministic codeHolds everything deterministic as ordinary code, exposed to the agent through clients, helpers and the like, rather than leaving it to the model.

How it stays safe

  1. Production is blocked in the services. Every API exposed for the skill is guarded by permissions so that it works only with non-production environments, so no wording of a request can get past it.
  2. New APIs wrap the existing ones. The APIs exposed for the skill are wrappers on top of the existing ones, so every existing check and nuance still runs, such as writing to the third-party auth service.
  3. Users never touch the APIs. Every call goes through the skill.
  4. Every request is validated first. The agent checks a request before it makes it.
  5. Unclear requests come back to you. When something is ambiguous, the agent asks, and that conversation happens in Slack.
  6. Two systems stay in step. Some changes touch both our app and our identity provider; if the sync fails, the previous value is restored.

Where it is now

Folks have started using it. Requests now rarely reach the platform team, and when one does, the team triggers the agent to handle it with this skill.

The point stays the same: access to non-production environments shouldn't mean waiting. With the agent it is self-serve and audited, and it is locked out of production.

Leonardo DiCaprio raising a champagne glass in The Great Gatsby
Access in one message, now possible.