Vaarta Identity Studio
Platform
AI agents & MCP

Let agents do real work. Keep every secret sealed.

Identity Studio is the authorization server for your AI agents. They discover what they may reach, a person consents once, and every call carries a token bound to one resource. Agents use API keys, logins and signing keys from Vaarta Vault without ever seeing them.

Book a demoHow it is secured
Vaarta Vault · Agent accessStep-up done
[Your AI agent] wants accessConnected over MCP · registered on this machine

This app named itself. Identity Studio has not checked who made it.

It can use this access only at Vaarta Credentials.
Use [API key item] at api.[host]
Sign its browser in to [site host]
For 1 hour · ask on my phone every use
DenyAllow
Why it is different

Autonomous work, with a person still in charge

Agents get real access to real systems. You keep the keys, the say, and the record.

Agents act, secrets stay sealed

Your agent calls the API, signs the digest or signs in the browser. It never receives the key, password or one-time code.

use_credential_http · sign_digest · the local credential bridge

Sensitive use waits for your thumb

Mark an item "ask every use" and each call needs a tap on the matching number on your phone.

Single-use approval bound to a hash of the exact request

Tokens bound to one resource

An agent's token names one resource as its audience. Every other API refuses it, and it is never passed on.

RFC 8707 resource indicators · no token passthrough

Stop one agent, or all, in one click

Consent is withdrawn, refresh chains revoked, and live tokens refused at the very next call.

Stop and Stop-all in the vault · RFC 7009 revocation

How it works

From an agent's first request to a result, never the secret

  1. 1AgentHits a 401The challenge names the resource's metadata (RFC 9728).
  2. 2AgentDiscovers and registersReads the authorization server (RFC 8414) and registers itself (RFC 7591).
  3. 3PersonSigns in and consentsCode flow with PKCE S256 and the resource; the consent screen names it in words.
  4. 4Identity StudioIssues a bound tokenAudience = that one resource. The refresh token rotates.
  5. 5AgentCalls a toolAsks for a grant on one item, then uses it: an API call, a browser sign-in, a signature.
  6. 6PhonePerson taps the numberOnly when the item asks on every use. The approval is single-use.
  7. 7AgentGets the resultA redacted response, signed_in, or a signature. Never the secret.
How we secure it

Every mechanism, named

The protections below are in the code today. The last three are in early access.

An OAuth 2.1 authorization server

Authorization code with PKCE S256, forced for every self-registered client. Refresh tokens rotate; a reused one revokes the whole chain.

RFC 6749RFC 7636OAuth 2.1

Protected resources agents can discover

A 401 carries WWW-Authenticate with resource_metadata, and the metadata names the authorization server and scopes.

RFC 9728RFC 6750MCP 2025-06-18

One resource per token, no passthrough

The token's audience is the credential resource, so ordinary app routes refuse it. Outbound calls carry only the item's secret, never the agent's token.

RFC 8707

Consent per agent, per item

A grant is one person, one agent, one item, the operations and hosts allowed, and an expiry: up to 30 days, 24 hours for signing. Approving needs a fresh step-up.

A live sign-in behind every call

Each request checks that the person's session is still live. Sign out, get locked or suspended, and the agent stops at its next call.

Human in the loop, by number matching

Items marked "ask every use" need a tap on Vaarta Authenticator. Each approval is spent once and bound to a hash of the method, URL, headers and body.

Use without reveal

Secrets are injected as a header, basic auth or query, over https only, to hosts on both the item's and the grant's allow-lists, with DNS pinned and redirects refused. Echoes are redacted.

Signing keys that never leave AWS KMS

sign_digest sends a digest; KMS signs with ECDSA P-256 or P-384, or RSA PSS or PKCS#1 with SHA-256 or SHA-512. Never SHA-1, never a raw message.

AWS KMS

Stop, revoke, disconnect

Stop one agent or all of them; RFC 7009 revocation withdraws consent and revokes refresh chains. No step-up is needed to end access.

RFC 7009

Registration and introspection

Self-registered clients are public PKCE clients with loopback or app-scheme redirects, purged after 7 days if nobody consents. Introspection gives no oracle.

RFC 7591RFC 7662

Live activity

The last 30 days of what each agent did: item, operation, host and outcome, refreshed every 15 seconds. Never a value.

The full audit trail

Every grant, use, release, signature and refusal is a hash-chained audit row, written before the value is answered. Counters are keyed by agent, never by person.

Machine-to-machine for services

Service APIs use client credentials with scopes your API defines: 30-minute tokens, 60 a minute per client.

client_credentials

Connected-agent limits per plan

Early access

A plan sets how many agents a person may connect.

Local-only release operations

Early access

Browser sign-in and run-with-secret reserved for the person's own local agent.

Conditional access on agent refresh

Early access

Access rules applied when an agent refreshes its token.

Autonomous browser sign-in

Sign the agent's browser in, without the model ever seeing the password

The Vaarta credential bridge is a local MCP server on the person's own machine, launched over stdio by their coding agent. It drives Chrome through DevTools, the same channel Playwright uses, and keeps every value out of the model's reach.

sign_in_browserSigns the agent's Chrome into a site with a stored login and the current one-time code.
run_with_secretRuns one command with an API key in one environment variable. Output comes back redacted.
ssh and vaarta-signSSH logins and file signatures with a key held in AWS KMS. Nothing secret reaches the machine.

How the password is protected while the browser is automated

  • Page scripts only find, tag, focus, empty and click. No script ever carries a value.
  • The value travels once, in DevTools Input.insertText, straight into the focused field, after checking it is the right field (a password only into type=password) on the host the release was made for.
  • The page's own submit is pressed at once. If anything fails, or the outcome is not confirmed, the password and code fields are emptied.
  • The DevTools endpoint is configured, never guessed, and must be loopback: 127.0.0.1, localhost or ::1.
  • Each release is for one host, and Identity Studio checks the tab's real URL against the grant.
  • The value is held in memory for one fill only. Nothing is stored, logged or returned.

How it stays autonomous, and persistent

  • One registered client per machine, which the person can see and disconnect in their vault.
  • The access token is bound to the credential resource and kept only in memory.
  • The refresh token sits in the OS keychain, rotated on every refresh and deleted when refused.
  • The person approves a grant once. After that the agent signs in and runs commands without asking, except for items that ask on every use.
  • A restart needs no new sign-in. Disconnecting in the vault, a grant ending or Stop-all ends it everywhere.
What the model seessigned_in or filled · an exit code and redacted output · the number to tap · refusal codes
What it never seesthe username, the password, the one-time code, the API key, the bridge's own token
MCP client configurationfrom the bridge README
{
  "mcpServers": {
    "vaarta-credentials": {
      "command": "python3",
      "args": ["-m", "vaarta_credential_bridge", "serve"],
      "env": {
        "VAARTA_IDS_URL": "https://<identity studio>",
        "VAARTA_CDP_URL": "http://127.0.0.1:9222"
      }
    }
  }
}

The risk that remains, stated

A model that also reads the page between the fill and the submit could see the field. That is why the submit is immediate and a failure empties the field. A command that writes a secret somewhere other than its output does so on its own; only what comes back on stdout and stderr is redacted.

Limits

What an agent can never do

  • Read a password, API key, one-time code or private key. No tool returns one.
  • Use its token at any API other than the one resource it was issued for.
  • Reach an item, operation or host the person did not grant.
  • Keep access after the grant expires, the person signs out, or they press Stop.
  • Approve its own request. Only the person's phone can.
  • Be granted payment cards or identity records.
  • Act without a record: every use and every refusal is in the audit trail.
services/credential_mcp.pythe 401 challenge
def challenge(error=None, description=None) -> str:
    """The `WWW-Authenticate` value (RFC 6750 §3 +
    RFC 9728 §5.1): it always names the resource's
    metadata document."""
    parts = []
    if error:
        parts.append(f'error="{error}"')
        if description:
            parts.append(f'error_description="{description}"')
    parts.append(f'resource_metadata="{protected_resources.metadata_url(RESOURCE)}"')
    return "Bearer " + ", ".join(parts)
Works with

Part of one platform

OAuth 2.1 & OpenID Connect The authorization server underneath.API security Machine clients and scoped keys.Passkeys & MFA The phone approval agents wait for.Vaarta Vault ↗ Where the secrets live.
Connected-agent allowances and every other limit are on the plans page.See plans →

Put your agents to work, safely

Connect your first agent, grant it one item for one hour, and watch every call in the activity view.

Book a demoStart free trial