Introducing ugrant: an OAuth token broker for CLI apps
I built ugrant because I kept wanting the same thing from local software: if I'm already logged into a SaaS product, I want small Unix programs to be able to act on that fact.
A watcher wants IMAP access. A one-shot classifier wants to hit an API. OpenClaw wants to share the same login context as a few tiny helper processes. None of those programs should need to own the full OAuth lifecycle.
That kept showing up in slightly different forms, so I built a tool for the shape of the problem.
ugrant is a small local token broker for Unix userspace. You log in once, keep grant custody local, and let independent processes reuse that authenticated context without turning every script into its own credential manager.
Point your agent of choice at ugrant.sh/llms.txt. It'll know what to do.
The use cases
This came from a few concrete annoyances.
Reusing IMAP auth across multiple small apps
Email was the clearest case.
I have more than one little process that wants Gmail / IMAP access:
- a watcher
- a triage tool
- an extractor
- a small process that classifies or normalizes inbound mail
They should be able to run independently. They should not each carry their own login flow, refresh logic, or stale credential story.
ugrant gives those programs a shared auth context with one custody model.
Sharing an OpenAI / Codex login across agentic tools
I want OpenClaw to use my login context. I also want small independently-running prompts to work too: a short classifier, a one-off summarizer, a tiny helper process.
That's a very normal Unix desire. One authenticated local context, many small consumers.
ugrant exists so a logged-in local system can delegate child-safe access to other processes without copying a full auth subsystem into each one.
Letting Unix userspace act like a logged-in SaaS app
This is the bigger thesis.
A lot of useful software is just the website's capabilities, exposed to local programs in a sane way.
If I'm already logged into a SaaS product, and that product has delegatable API access, I want local tools to be able to use that fact. I want to say: this machine, this user, this profile, this command.
QuickStart
curl -fsSLo /tmp/ugrant-install.sh https://www.ugrant.sh/install.sh && sh /tmp/ugrant-install.sh
ugrant init
ugrant profile add \
--name gmail \
--service google-imap \
--client-id <id> \
--client-secret <secret>
ugrant login --profile gmail
# ugrant prints a login URL
# open it, approve the app, then paste back the final redirect URL
ugrant exec --profile gmail -- python sync_mail.py
# ugrant injects the auth data as environment variables for the child processThat shape is the whole point: log in once, then let small programs reuse that authenticated context cleanly.
Why I don't think PATs are a satisfying answer
Personal access tokens solve the wrong problem too bluntly.
If a PAT is exfiltrated, the original system often keeps working. The attacker can use it. The legitimate user can keep using it. Compromise can stay quiet for a long time.
Refresh-token-based systems do have a property I genuinely like: they are serial.
If a refresh token is intercepted and used elsewhere, the legitimate system tends to start failing pretty quickly. The working system becomes a broken system. The user gets pulled into the loop because something that used to work has stopped working.
That's a much better compromise signal.
It reduces the value of quiet theft. It reduces the reward for a compromiser. And it improves time-to-notice, which matters a lot in practice.
A credential model that degrades noisily under theft is often better than one that remains quietly valid.
Why this stays local
I wanted ugrant to feel boring in the best way.
It stores grant state locally. It refreshes on use. It injects only the env the child process actually needs.
It also does not require a long-running broker daemon.
The Unix process model is already good: separate processes, shared durable state, explicit invocation, clear failure boundaries.
If five different commands need the same credential context, they can still be five different commands.
Why now
This feels more useful now because we suddenly have many more small independent processes worth authenticating.
A personal agent. A classifier. A cron job. A watcher. A triage process. A background sync tool. A one-shot prompt runner.
All of those get worse when they each need bespoke auth logic. They also get riskier when the answer is a broad static token sprayed everywhere.
So ugrant is my attempt to make one part of that future less janky.
If it works, your local tools get to behave more like first-class software citizens of the accounts you're already logged into.
And if it fails, at least I'll have one fewer excuse for why my IMAP tooling turned into a pile of cursed one-offs.
I'm Aidan. I build things on the web. Occasionally I get annoyed enough by auth UX to build a tool about it. More at outsidetheboxmodel.com.