Skip to main content
Glama
Erseni

vault-ask (Erseni Vault)

secrets-component

Zero-knowledge, one-time secret sharing. End-to-end encrypted in the browser. The server only ever stores ciphertext. Supports both sending and requesting secrets without requiring any account.

Part of the Erseni open-source components.

Status: early development. API and on-disk format may change until the first tagged release.

Primary development happens in Erseni's internal monorepo. This repository is a public mirror, kept in sync via Jenkins after every successful production deploy. Issues and merge requests are welcome; see CONTRIBUTING.md.

Features

  • Send a secret: create a one-time link, recipient decrypts in the browser, secret self-destructs after viewing.

  • Request a secret: create an inbound link, send it to a third party (customer, colleague) who submits a secret without an account. You retrieve it once with your private key.

  • End-to-end encryption: AES-GCM 256 for sending, X25519 + ECIES for requesting. All crypto in the browser via the native Web Crypto API. The server never sees plaintext.

  • No accounts: neither sender nor receiver needs to sign up.

  • Auditable: deterministic build, source SHA embedded in every HTML response, SRI hashes on every script.

  • Secrets for AI agents: cli/ contains vault-ask, a CLI and MCP server that request a secret from a person and hand it to exactly one command or file, masked in every output and never shown to the agent, and that send a generated secret to a person as a one-time link.

Related MCP server: Vaulted MCP Server

Where it runs

The component runs as part of Erseni Vault, hosted in the EU. It is not a standalone application: it depends on Erseni's internal framework, and this repository cannot be installed or self-hosted on its own. The source is published so that the cryptography and the server behaviour can be audited.

vault-ask in cli/ is the exception: it is a standalone Node.js tool that talks to Erseni Vault.

Security model

  • Secret plaintext never leaves the sender's browser.

  • Encryption keys are transported in the URL fragment (#k=...), which browsers never send to servers.

  • Secrets are deleted on first retrieval (atomic DELETE ... RETURNING).

  • Expired secrets are purged every minute by a cron job.

  • No access logs, no IP retention, no backups of the secrets tables.

See docs/ARCHITECTURE.md and docs/THREAT-MODEL.md.

Verifying a running instance

Every page served by a secrets-component instance includes a <meta name="build-sha" content="..."> tag. Match that SHA against a tag in this repository to confirm the deployed code.

curl -s https://secrets.example.com/send | grep build-sha

License

AGPL-3.0-or-later. See LICENSE.

Security disclosure

See SECURITY.md.

Available Tools

3 tools
request_secretA

Use this whenever you need a password, token, API key or other secret from the user, for example "I will give you my database password" or "you need my API key for X". Never ask the user to type or paste a secret into the chat. Asks the user for one or more secrets and writes them into a .env file or a file, without the values ever passing through this conversation. First call without request_id: returns a link. Show it to the user, then call again with the returned request_id; that call waits for the answer and writes the file with permissions 600. The result only contains names and lengths, never a value.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileNoWrite the single requested value into this file
namesNoNames of the values to ask for, for example ["DB_PASSWORD"]
env_fileNoWrite NAME=value lines into this .env file
request_idNoThe id returned by the first call
ttl_secondsNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and does it well: it discloses the two-phase flow (first call without request_id returns a link to show the user; second call with request_id blocks and writes the file), the 600 file permissions, and the return content ('only contains names and lengths, never a value'). This is substantive disclosure beyond any structured field.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the primary use case and prohibition before moving to the mechanics and result format, and each sentence carries information. It is somewhat long for a single tool, but the two-phase flow justifies most of the length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations, the description compensates by describing the return value and the blocking behavior. The main gap is ttl_seconds semantics (expiry of the request), which is undocumented in both the schema and the description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 80%, and the description adds genuine meaning beyond it by explaining the two-phase semantics of request_id (absent on the first call, supplied on the second) and clarifying that file/env_file receive the secret values. It does not explain ttl_seconds, which is the parameter with no schema description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource pair ('asks the user for one or more secrets and writes them into a .env file or a file') and adds a distinguishing mechanism ('without the values ever passing through this conversation') that separates it from siblings like send_secret or run_with_secret. An agent can tell what this does and why it differs without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear trigger ('Use this whenever you need a password, token, API key or other secret from the user') with concrete examples, plus a strong prohibition ('Never ask the user to type or paste a secret into the chat'). It stops short of naming the sibling alternatives explicitly, but the usage context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_with_secretA

Use this whenever a single command needs a password, token, API key or other secret from the user, for example "connect to the database with my password" or "deploy with my API token". Never ask the user to type or paste a secret into the chat. Asks the user for one or more secrets and runs exactly one command with them as environment variables. The user sees the command before entering anything, and only this command can receive the values. First call without request_id: returns a link. Show it to the user, then call again with the returned request_id; that call waits for the answer, runs the command and returns its exit code and its output with every value masked.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwdNoWorking directory for the command
namesNoNames of the values to ask for, for example ["DB_PASSWORD"]
commandNoThe command and its arguments, for example ["psql", "-h", "db.example.com"]
request_idNoThe id returned by the first call
ttl_secondsNo

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and does so thoroughly: two-phase handshake (first call returns a link, second call with request_id waits and executes), the security model (user sees the command before entering anything, only that command receives the values), and the return shape (exit code plus output with every value masked).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical 'when to use this' guidance is front-loaded in the first sentence and the two-phase flow is laid out in sequence. Slightly repetitive in restating the secret concept across the trigger examples and the summary sentence, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema, the description compensates by explaining the return values and the asynchronous request_id flow completely. The only gap is that ttl_seconds is undocumented in both the schema description and the description text.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 80%, so the schema documents most fields itself. The description adds real meaning beyond it by explaining the request_id lifecycle ('call again with the returned request_id') and that names drives which secrets the user is prompted for, though ttl_seconds and cwd get no added context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it asks the user for secrets and runs exactly one command with them as environment variables. It is instantly distinguishable from a plain secret-request tool because it executes a command, though it never names the sibling tools request_secret or send_secret to make the boundary explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Strong trigger condition is given ('use this whenever a single command needs a password, token, API key') plus a hard rule ('never ask the user to type or paste a secret into the chat'). It stops short of stating when not to use it or which sibling to prefer for the non-command case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_secretA

Use this whenever the user asks you to generate, create or send them a password, token, API key or other secret, for example "generate a password for my database", "generier mir ein Passwort" or "send me the key". Do not generate a secret any other way and never write one into the chat. Generates the value locally (32 letters and digits unless length or charset say otherwise) or takes it from from_file or from_env, encrypts it on this machine and returns only a one-time link that shows the value once in the browser. Give the user that link. With env_file, file or command the same value also goes to that destination (needs name except for file), so the system and the link hold the same value. The result contains the link, its expiry and the length, never the value.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwdNoWorking directory for relative paths and the command
fileNoAlso write the value into this file (permissions 600)
nameNoName of the value, for example "DB_PASSWORD". Default label on the page, and the variable name for env_file and command
labelNoLabel shown above the value on the page, for example "Database password for app@db.example.com"
lengthNoLength of the generated value, default 32
charsetNoCharacters of the generated value, default alnum
commandNoAlso run this command with the value in the environment variable NAME, for example ["./scripts/set-db-password"]. Its output comes back with the value masked
env_fileNoAlso write NAME=value into this .env file (permissions 600)
from_envNoSend the value of this environment variable of the server process instead of a generated value
from_fileNoSend the content of this file instead of a generated value
ttl_secondsNoHow long the link stays valid, default 86400

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: generation is local, the value is encrypted on this machine, only a one-time link is returned that shows the value once, the value never appears in chat, and the same value is routed to env_file/file/command destinations. It even discloses that command output returns with the value masked.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a dense single paragraph that front-loads the usage trigger and routing rule before the mechanics, which is the right ordering. For an 11-parameter tool this length is justified, though a couple of clauses ('never write one into the chat', 'shows the value once') restate the same security point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description explicitly covers the return shape ('the link, its expiry and the length, never the value'), which is exactly what the agent needs. Combined with the generation/encryption/destination behavior, nothing material is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter meaning the schema lacks: the default is 32 letters and digits unless length or charset override it, name is required except for file, and the same value flows to every destination. It does not document every parameter (e.g. cwd, ttl_seconds defaults are left to the schema), keeping it at 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it generates, takes, encrypts and returns a one-time link for a password/token/API key. It is clear about what the tool produces, but it never names or contrasts with its siblings request_secret and run_with_secret, so an agent cannot fully disambiguate from the description alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit trigger ('whenever the user asks you to generate, create or send them a password, token, API key'), concrete examples including a non-English one, and a firm negative rule ('Do not generate a secret any other way and never write one into the chat'). It stops short of naming alternative tools, so it does not reach a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.2.1
    • First observedrequest_secret
    • First observedrun_with_secret
    • First observedsend_secret

TDQS

A4.3/5.0

Scored across 3 tools

Disambiguation4/5

The three tools split along a clear axis: request_secret pulls secrets inbound into a file, run_with_secret uses a secret to execute one command, and send_secret generates/returns a secret outbound. request_secret and run_with_secret share the same ask-the-user/link flow and could momentarily be confused, but their end outcomes (write a file vs. run a command) are clearly spelled out.

Naming Consistency5/5

All three follow a strict verb_secret pattern (request_secret, run_with_secret, send_secret). The verb meaning is consistent: the action describes what happens to the secret (request in, run with, send out).

Tool Count4/5

Three tools is on the lean side but each covers a genuinely distinct secret lifecycle stage (acquire, use, issue). The set feels deliberately minimal rather than padded, which suits a security-sensitive vault.

Completeness4/5

Inbound acquisition, command usage, and outbound distribution with multiple destinations (file, env_file, command) are all covered, giving a coherent lifecycle. Minor gaps: no explicit tool for listing, rotating, or revoking previously stored secrets, though these could be handled outside the surface.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Self-hosted, zero-knowledge encrypted, self-destructing secrets for secure agent-to-agent coordination
    3
    AGPL 3.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI coding agents to securely inject API keys and secrets into environment files, configs, or commands without the agent ever seeing the secret values.
    3 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI coding agents to manage and use API keys and secrets without ever seeing their values, by checking availability, listing names, requesting missing values, and running commands with injected secrets and redacted output.
    39 npm
    MIT