How to

How to build an access request and approval app

Access is requested in a ticket, granted by whoever sees it first, and never reviewed. Here is the model behind an app that fixes that, the prompts to build it, and what it takes to run it.

The short answer

An access request app is four parts: a catalogue of systems and roles with a named owner for each, approval by that owner, grants that expire by default, and a review cycle that produces evidence. The change that reduces the most risk is making access expire. Permanent grants accumulate, and no periodic review ever fully reverses that accumulation because revoking access always feels riskier than leaving it.

access-requests.helix-app.ai

Access requests

6

Waiting on you

23

Expiring in 30 days

4

Permanent grants

0

Leavers still holding access

System

Data warehouse

Role

Analyst

What this lets you do

Query every table except payroll, and export results

Written for the approver, not the administrator

Why you need it

Building the churn model for the CS headcount case

Access ends

In 90 days

Permanent needs a reason and reports separately

Goes to

Owner of the data warehouse

Not your manager, who cannot judge this

A sketch of the request. The plain-language line is the point: an approver who cannot tell what a role actually permits approves everything, and db_reader tells them nothing.

What matters here

  • An access app is four parts: a catalogue with named owners, owner approval, time-bound grants, and a review cycle with evidence.
  • Default to expiry. Permanent access accumulates, and periodic reviews never fully claw it back.
  • The system owner approves, not just the requester's manager. A manager rarely knows what a role in a system actually permits.
  • Describe each role in the catalogue by what it lets someone do, in plain language. Approvers cannot assess a permission string.
  • Separate the request record from the grant record. What was asked for and what was given are not always the same, and the difference matters.
  • An access request app grants access to other systems, so managed credentials and its own access control are the core of the build, not an addition.

Who this is for

You run IT, security or operations. You already know your systems and roughly who has access. What you want is requests that route to the right owner, grants that expire, and an access review that is a report rather than a project.

How it works in practice

What happens when somebody needs access to something, and what stops it accumulating forever.

  1. 1

    They browse a catalogue, not a ticket form

    Every system and role, with a plain-language description of what it actually permits and how sensitive it is.

  2. 2

    The request goes to the system owner

    Not just the requester's manager, who usually cannot say what a role in that system permits.

  3. 3

    The approver sees what this person already holds

    Which catches the slow accumulation that makes one person able to do everything.

  4. 4

    The grant has an expiry by default

    Permanent requires an explicit choice and a reason, and reports separately.

  5. 5

    Extension goes back through approval

    Not automatic renewal. An auto-renewing grant is a permanent grant with extra steps.

  6. 6

    Reviews that produce evidence

    Confirmed, revoked with a reason, or not reviewed. Auto-confirming turns the control into paperwork.

What an access request app is made of

An access request app is not a ticket form. It is four parts, and the third is the one that changes the risk profile.

A catalogue

Every system, the roles available in it, what each role actually permits in plain language, its sensitivity, a named owner, and whether it requires additional approval.

Owner approval

Requests routed to the person accountable for that system, with the manager as a second step where sensitivity requires it. Not a shared IT queue.

Time-bound grants

Every grant has an expiry unless explicitly marked permanent with a reason. Renewal is a decision, and expiry is the default.

A review cycle

Periodic recertification by system owners, producing a record of what was confirmed, what was revoked, and what was not reviewed.

These prompts start from a Helix project, which is what handles sign-in, credentials and hosting. Start with Helix

The prompts

Paste these into Claude Code, Codex or Cursor in order. Each one leaves you with something that runs, so you can stop after any step.

  1. The catalogue, written for the approver

    What can be asked for, and what it actually means.

    In this Helix project, build me an access request and approval app.
    
    Start with a catalogue. Every system: name, description, a named owner,
    sensitivity from low to restricted, whether it holds personal data, and
    whether it is in scope for any compliance regime. Then the roles available
    in each system, with a default grant duration, whether it can be permanent
    at all, and whether it needs a second approver.
    
    Now the field that matters most. For every role, write a plain-language
    description of what it actually lets somebody do, aimed at an approver
    rather than an administrator. "Can read and export all customer records
    including contact details" is useful. "db_reader" is not, and an approver
    who cannot tell what they are granting will grant everything.
    
    Make the catalogue browsable and searchable, with sensitivity clearly
    shown. And flag any system with no named owner and any role with no
    description, because both make every downstream approval meaningless.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
  2. Route it to somebody who can actually judge it

    The system owner, with the requester's history in front of them.

    Requests need a business justification in free text plus a reason from a
    short fixed list, and reject empty justifications.
    
    Route to the system owner. Add the requester's manager as a required first
    step where the role sensitivity is high or restricted.
    
    Show the approver: who is asking, their role and team, what this access
    permits in plain language, what access they already hold, and whether
    people in comparable roles have it. That third item is the one that
    catches slow accumulation, where somebody has quietly ended up able to do
    everything because each individual request looked reasonable.
    
    Give every approver a deputy with automatic reroute. Access requests that
    stall get solved by asking a colleague directly, which is exactly the
    behaviour this app exists to replace.

    Worth knowing. Showing what the requester already holds is the cheapest privilege-creep control there is.

  3. Make access expire

    The change that does more for risk than anything else here.

    Keep grants separate from requests. What was asked for and what was given
    are not always the same, and that difference is exactly what an auditor
    asks about.
    
    A grant records the person, system, role, when it was granted and by whom,
    when it expires, and if revoked, when and why.
    
    Default the expiry from the role's duration. Permanent requires an
    explicit choice and a reason, and reports separately so I can see how much
    of it there is.
    
    Notify the holder and the system owner before expiry, with a one-click
    extension request that goes back through approval rather than renewing
    automatically. An auto-renewing grant is a permanent grant with extra
    steps.
    
    On expiry, mark it expired and create a revocation task for the system
    owner, with evidence required on completion. Then give me the view
    everybody wants and almost nobody has: current access, per person and per
    system.

    Worth knowing. Permanent access accumulates and periodic review never fully claws it back, because revoking always feels riskier than leaving it.

  4. Reviews that are honest about themselves

    Recertification, and the report that should be empty.

    Generate a review per system on a schedule. The system owner sees every
    current grant and confirms, reduces or revokes each one, with a reason
    required for anything revoked.
    
    Anything not reviewed by the due date reports as not reviewed. Do not
    auto-confirm and do not auto-revoke. Both hide the fact that the review
    did not happen, and the whole point is to know.
    
    Produce a review record: what was confirmed, what was revoked, what was
    not reviewed, by whom and when. Exportable.
    
    Then standing reports: permanent grants by system, people holding access
    to more than a threshold number of high-sensitivity systems, access
    granted but never used if I can give you login data, and grants belonging
    to people who have left.
    
    That last one should be empty. When it is not, it is the most urgent thing
    in the app.
  5. Connect it to real systems

    The step that turns a working prototype into something with your data in it.

    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Okta>. Read groups and roles, and provision or revoke access when a grant
    starts and expires.
    
    <each target system>. Grant and remove the specific role, and record the
    evidence that it happened.
    
    <Workday>. Read leavers, so the report of people who left still holding
    access is real.
    
    <Slack>. Route a request to the system owner and warn a holder before a
    grant expires.
    
    <Google Workspace admin>. Grant and remove access to files, groups and
    shared drives, which is where a lot of real access lives.
    
    <Jira>. Raise the revocation task for systems that cannot be automated, so
    it is tracked rather than remembered.
    
    <Vanta>. Feed the access review evidence in, so the review is recorded
    where audits get answered from.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.

    Worth knowing. Every name in angle brackets is a placeholder for whatever you run. Helix holds the credential as a workspace authentication, so the app references an alias and never the secret itself.

  6. Ship it

    The last step of every build: a URL, and the right people on it.

    Deploy my app.

    Worth knowing. Your assistant runs helix deploy underneath and the app comes back as a URL. An app that grants access to your other systems has to be at least as well protected as what it grants, so set Access Control before sharing and scope owners to their own systems.

What it connects to

This app grants access to your other systems, so what it can reach is the whole security question.

  • Okta

    Read groups and roles, and provision or revoke access when a grant starts and expires.

  • Each target system

    Grant and remove the specific role, and record the evidence that it happened.

  • Workday

    Read leavers, so the report of people who left still holding access is real.

  • Slack

    Route a request to the system owner and warn a holder before a grant expires.

  • Google Workspace admin

    Grant and remove access to files, groups and shared drives, which is where a lot of real access lives.

  • Jira

    Raise the revocation task for systems that cannot be automated, so it is tracked rather than remembered.

  • Vanta

    Feed the access review evidence in, so the review is recorded where audits get answered from.

Each line says whether the app reads, writes or both. Anything not described as writing should be read only.

Named systems are the ones most teams actually run, not a list of the only ones that work. Swap in whatever you use.

Each connection is an authentication in your Helix workspace, referenced by alias. The app names the connection it wants and never holds the credential, so nothing here ends up in your code and any of it can be rotated or revoked without a redeploy.

Running it for real

The build gets you a working app. It decides who gets access to your other systems, which makes how it is run more important than what it computes.

AI Deployment

Get it to a URL people can open

One command takes the app from your assistant to a live address, so the people who need it get a link rather than instructions for running it locally.

App Security

Put your identity provider in front of it

An app that grants access must be at least as well protected as what it grants. SSO means people sign in with their existing account, and access within the app is scoped so owners approve only for their own systems.

App Security

Connect the system of record with managed credentials

Provisioning and revoking in the target systems needs real credentials. Granting them to the app rather than pasting keys into it means they can be rotated or revoked without a redeploy, and the grant itself is recorded.

App Registry

Put a name on it

Every app carries a named owner and an entry IT can see, so the tool does not become nobody's problem when the person who built it changes role.

Cost Management

Know what it costs to run

Per-app spend visibility, with budgets and caps, so an internal tool cannot quietly become a line item nobody can explain.

Questions people ask

What is an access request and approval app?

It holds a catalogue of systems and roles with named owners, routes requests to the owner who can assess them, issues grants that expire by default, and produces the evidence an access review needs.

Why should access grants expire by default?

Because permanent access accumulates and periodic review never fully reverses it. Revoking access always feels riskier than leaving it, so the only reliable control is that access ends unless somebody actively decides to extend it.

Who should approve an access request?

The owner of the system, with the requester's manager as an additional step for sensitive roles. A manager typically cannot say what a given role in a system actually permits, so manager-only approval is a signature rather than a decision.

Why separate the request record from the grant record?

Because what was requested and what was granted are not always the same. Someone asks for admin and receives read-only, or asks for 30 days and receives 90. An auditor asks about the grant, and only a separate record answers precisely.

What should an access review produce?

A record of what each owner confirmed, what they revoked with a reason, and what was not reviewed at all. Auto-confirming unreviewed access turns the control into paperwork, and auto-revoking hides the same failure differently.

Can I build this without an engineering team?

Yes. The prompts here are written for Claude Code, Codex or Cursor and stage the build. The work outside the code is writing plain-language descriptions of what each role permits, which is what makes approvals real.

Last reviewed September 2026.

Build it, then run it properly

Helix is the governed runtime for AI-built apps. Deploy what you build, put SSO in front of it, connect it to your systems with managed credentials, and give it a named owner.