-
-
Chat Interface
-
Consent Scope Visualiser Toggle actions between direct execution and CIBA step-up authentication
-
Real-Time Audit Log Every API call logged with timestamp, service, action, token hash (never full token), and result.
-
Live Demo — OpenClaw Bridge Simulate agent tool-calls. Zero tokens in the payload — ever.
-
Step-Up Authentication CIBA Push Notification Rejected
-
Step-Up Authentication CIBA Push Notification Accept
-
Revocations
Inspiration
Every week brings a new story: an AI coding assistant that accidentally committed API keys to a public repo, a chatbot that leaked session tokens into its context window, a workflow agent that stored OAuth credentials in plaintext inside a prompt template. The pattern is always the same — developers give AI agents too much access because there's no middle ground between "no access" and "full credentials."
We started asking a simple question: What if an AI agent could send an email on your behalf without ever knowing your Gmail password or OAuth token?
The answer led us to Auth0's Token Vault — a system designed to store and retrieve credentials server-side, outside the agent's reach. But we quickly realized that vault isolation alone isn't enough. You also need:
- A way to scan and reject agent payloads that try to smuggle credentials
- Per-action consent controls so users decide which actions need explicit approval
- A step-up authentication flow (CIBA) that pauses sensitive actions until the user approves from their own device
- Instant revocation that cuts off access with a single click
- A complete audit trail that logs every action without ever recording a raw token
That's GhostKey — not just a vault wrapper, but a full trust and governance layer for AI agents.
What It Does
GhostKey sits between AI agents and the services they act on (Gmail, Google Calendar, Slack). It enforces a zero-trust architecture where:
🔐 Token Vault Isolation
OAuth tokens live exclusively in Auth0's Token Vault. They are fetched server-side via getTokenFromVault() and never appear in agent payloads, UI responses, logs, or the browser.
🛡️ Credential Scanning
Every incoming agent payload is scanned against a pattern library. If the request contains anything that looks like a token, secret, API key, or password, the request is rejected before execution and the attempt is logged.
⚡ CIBA Step-Up Authentication
Users configure which actions are "sensitive" (e.g., sending mass email, deleting files, sharing externally). When an agent tries to execute a sensitive action, GhostKey triggers a Client-Initiated Backchannel Authentication (CIBA) flow — a real-time approval modal with a countdown timer. The user approves or denies. No approval = no execution.
🔌 Instant Revocation
One click disconnects a service. The moment you revoke, the next agent call returns 403 CONSENT_REQUIRED. There's no grace period, no cached token, no stale session. Trust is deleted instantly.
🎛️ Per-Action Consent Dashboard
A visual consent scope visualiser lets users toggle individual actions between "direct execution" and "step-up required" — per service, per action. You control exactly how much autonomy your agent has.
📋 Full Audit Trail
Every connect, revoke, action execution, CIBA approval, CIBA denial, and policy change is logged with rich metadata — timestamps, action types, services, outcomes, and token hashes (never raw tokens). The audit page supports filtering, CSV export, and real-time updates.
🤖 AI Agent Chat
A streaming chat panel lets you interact with an AI agent that routes all its tool calls through the GhostKey bridge — demonstrating the zero-trust flow in real time.
The Core Flow
1. AI agent sends { service, action, params } — NO tokens
2. GhostKey scans the payload for credential leaks
3. Policy engine checks if the action requires CIBA step-up
4. If sensitive → user approves/denies on their device
5. Token is fetched server-side from Auth0 Token Vault
6. Target API is called with Bearer token, then stripped from the response
7. Audit entry is stored with action metadata and token hash only
How We Built It
Frontend
- React 18 with TypeScript and Vite 5 for fast development
- Tailwind CSS with shadcn/ui components and Radix Primitives for accessible, polished UI
- Framer Motion for smooth hero animations, staggered reveals, and glassmorphic effects on the landing page
- Real-time dashboard powered by Supabase Realtime subscriptions — audit entries and service state updates appear instantly
- Streaming AI agent chat panel with live token-flow annotations
Backend
- Node.js + Express backend server with Auth0 JWT middleware for protected API routes
- Supabase Edge Functions (Deno runtime) serving as the primary bridge API (
agent-act,ai-agent) - Supabase Postgres for persistent storage of service state, audit logs, sensitive action configurations, and consent policies
Auth & Security Layer
- Auth0 Token Vault —
getTokenFromVault()fetches OAuth tokens server-side; tokens never touch the frontend - Auth0 Management API — resolves user email addresses to Auth0
user_idvalues for vault token lookup - CIBA (Client-Initiated Backchannel Authentication) — step-up approval flow for sensitive actions with configurable timeout
- Supabase Auth — handles dashboard session management (login, registration, session persistence)
- Credential Scanner — regex-based pattern matching against known token/secret formats in agent payloads
Architecture
┌─────────────┐ POST /agent/act ┌──────────────────┐
│ AI Agent │ ──────────────────────── │ GhostKey Bridge │
│ (no tokens) │ { service, action } │ │
└─────────────┘ │ 1. Scan payload │
│ 2. Check policy │
│ 3. CIBA if needed│
└────────┬─────────┘
│
getTokenFromVault()
│
┌────────▼─────────┐
│ Auth0 Token │
│ Vault │
└────────┬─────────┘
│
Bearer token (server-only)
│
┌────────▼─────────┐
│ Gmail / Calendar │
│ / Slack API │
└────────┬─────────┘
│
Token stripped from response
│
┌────────▼─────────┐
│ Supabase Audit │
│ Log │
└──────────────────┘
Challenges We Ran Into
CORS with custom headers — Our first approach passed Auth0
user_idvia custom HTTP headers, which broke browser preflight checks. We refactored to use JSON body fields and query parameters, which simplified the integration and eliminated CORS issues entirely.Deployment divergence — Local development would work flawlessly, but the deployed Supabase Edge Function often served a stale version. We learned that deployment verification is a first-class product concern for hackathons — you must verify the live artifact, not just the local code.
Token Vault identity resolution — Auth0's Token Vault requires the exact
user_idto fetch tokens, but our app only knows the user's email at auth time. We built a resolution pipeline that queries the Auth0 Management API to mapemail → user_id → vault token, handling edge cases like multiple identities and missing connections.Reset state management — The demo reset flow needs to atomically clear: Supabase backend state (services, audit logs, sensitive actions), frontend React state, localStorage flags, and suppress auto-reconnect triggers. Getting all of these to reset in the right order — without race conditions or stale UI — took several iterations.
Browser-safe credential scanning — We needed to reject payloads containing embedded tokens and secrets while not false-positiving on legitimate payloads. Tuning the regex patterns to catch real credential formats (Bearer tokens, API keys, OAuth secrets) without blocking normal user content required careful iteration.
CIBA flow timing — The step-up approval modal needs a countdown timer that's synchronized with the backend's CIBA timeout. If the timer expires client-side before the server resolves, or vice versa, the UX breaks. We centralized the timeout authority on the backend and used it to drive the frontend countdown.
Real-time audit synchronization — Audit entries are written by the Edge Function but displayed by the React frontend. Getting Supabase Realtime subscriptions to reliably deliver new entries — including during rapid sequences like connect → act → revoke — required careful channel management and deduplication.
Accomplishments That We're Proud Of
Zero token exposure, end to end — From the moment an agent sends a request to the moment the audit entry is written, no OAuth token ever appears outside the server. The browser never sees it. The agent never sees it. The logs never contain it. This is the core promise of GhostKey, and we delivered it.
Real Gmail API integration — When Auth0 Token Vault credentials are configured, GhostKey actually sends emails via the Gmail API using vault-fetched tokens. It's not a mock — it's a real API call with a real token that the agent never touched.
Live CIBA step-up flow — Sensitive actions trigger a real-time approval modal with a countdown timer. The user sees the action details, approves or denies, and the result is logged. This is the "trust checkpoint" that makes GhostKey more than just a vault wrapper.
Production-quality audit trail — Every action is logged with structured metadata: service name, action type, outcome, token hash (SHA-256, never raw), CIBA details, timestamp, and user context. The audit page supports filtering by service and action type, and offers CSV export.
Clean demo reset — One button resets all services, audit logs, consent policies, sensitive action configs, localStorage flags, and React state back to defaults. This makes the demo infinitely repeatable — critical for hackathon presentations.
Beautiful, animated landing page — A polished landing page with Framer Motion animations, glassmorphic cards, gradient backgrounds, and a clear narrative flow. It tells the GhostKey story before you even log in.
Streaming AI agent chat — The chat panel demonstrates real agent-to-service flows through GhostKey, with streaming responses that annotate the trust flow in real time.
What We Learned
Token Vault is foundational, not sufficient — Storing tokens in a vault is table stakes. The real value comes from combining vault isolation with credential scanning, CIBA step-up auth, instant revocation, per-action consent controls, and comprehensive auditability. It's the combination that creates a trust layer.
Narrative matters as much as implementation — Framing the problem as "your AI acts, it never sees the key" resonated far more than listing technical features. A clear, memorable product story is as important as the code behind it.
Depth beats breadth — Three services (Gmail, Google Calendar, Slack) implemented with full connect → revoke → act → step-up → audit flows gave us a much stronger demo than ten services with shallow integrations. Judges (and users) care about completeness, not checkboxes.
Auth0's power is in the composition — Token Vault + Management API + CIBA isn't three separate features — it's one coherent trust architecture. Token Vault provides isolation, the Management API provides identity resolution, and CIBA provides human-in-the-loop approval. Together, they solve a problem none of them could solve alone.
Demo reliability is a feature — The reset button wasn't an afterthought — it became one of our most important features. Being able to confidently demo the same flow multiple times, with fresh state every time, is what separates a polished product from a prototype.
Real-time UI drives trust — Seeing audit entries appear in real time as actions execute gives users confidence that the system is actually working. Static logs don't create the same level of trust. The Supabase Realtime integration was worth every hour we spent on it.
What's Next for GhostKey
- Full Auth0 Universal Login — Replace Supabase Auth with Auth0 Universal Login for a unified identity layer across the entire stack
- Real CIBA device push — Implement phone-backed approval via push notification instead of an in-browser modal, for true out-of-band step-up authentication
- Additional service integrations — GitHub (repo actions), Notion (page creation), Linear (issue management), and more
- Role-based approval policies — Delegated consent for teams: managers approve on behalf of reports, admins set org-wide policies
- Compliance-ready audit exports — Downloadable PDF and CSV reports with structured audit data, suitable for SOC 2 and ISO 27001 evidence
- Multi-tenant support — Organizations managing agent access policies for entire teams, with centralized admin dashboards
- Token Vault health monitoring — Proactive alerts when vault tokens are near expiry or when connected services revoke OAuth grants
- Agent identity verification — Verify which AI agent is making the request, not just which user owns the token, enabling per-agent trust policies
Blog Post
The Moment We Stopped Trusting Our Own Agent
Three days into the hackathon, we had a working prototype. Our AI agent could connect to Gmail, draft an email, and send it. We were thrilled — until we opened the browser's Network tab and saw the OAuth token sitting right there in the response payload. Our "secure" agent had been leaking credentials the entire time.
That was the wake-up call. We'd been so focused on making the agent work that we forgot to ask whether the agent should even see the token. The answer, obviously, was no.
Auth0's Token Vault changed the architecture overnight. Instead of passing tokens through our bridge and hoping nothing logged them, we moved to a model where getTokenFromVault() runs exclusively on the server. The agent sends a clean { service, action, params } payload. The vault fetches the token. The API call happens. The token is stripped before anything returns to the client. Simple in concept — surprisingly tricky in practice.
The hardest part wasn't the vault itself — it was identity resolution. Token Vault needs an Auth0 user_id, but our app knows users by email. We had to build a pipeline that queries the Management API, resolves the identity, handles edge cases like missing connections, and then fetches the token — all within a single request cycle.
But the moment it worked — the moment we watched an email get sent through Gmail with a token that never appeared anywhere outside the server — we knew we had something real. Not a demo. Not a proof of concept. A genuine trust layer.
That's what Token Vault unlocked for us: the confidence to let an AI act without the anxiety of it knowing.

Log in or sign up for Devpost to join the conversation.