Using Vyre
Vault
The Vault keeps your credentials sealed at rest and releases them one item at a time, only to a module, watcher or agent you granted that item to. Agents use items by name and never see them. People share items by pass, and when someone leaves, one command revokes everything they hold and lists what to rotate. It is also a password manager for you: logins with one-time codes, cards, notes, API keys, env sets and SSH keys, with a generator, import, and autofill in the browser.
The rule that has no off switch
No value from the Vault appears on any screen, log or event, except to a person who has just proved presence on their own device, for that one value. Never to a model, an agent, a log or an event. This is rule 8 of Vyre's nine security rules, and it cannot be switched off.
In practice:
vault.list,vault.item,vault.search,vault.audit,vault.history, events, logs, errors and the MCP listing carry names, kinds, field names and hosts. Never a value.vault.putrefuses Claude. Values come fromvyre vault put's hidden prompt, from a file Vyre reads itself (vault.import), or from a module. Claude is never the channel a value travels through.- Showing, copying or filling a value needs you to prove you are present, with Touch ID, a passkey or a code typed in your terminal. See presence. A call from Claude alone cannot pass it.
Vyre asks you to prove you are there (Touch ID on a Mac, a passkey in the Vyre app or on the phone) for three kinds of thing: pairing a new Mac, releasing a vault secret (show, copy, fill, a one-time code, a backup), and anything that goes out as you, which is a send, a post, a payment or a delete. Reading a list of names asks for nothing. Unlocking your personal vault with its password asks for the password itself and nothing else, and Touch ID unlock asks for Touch ID; either one only opens the vault, and a secret still needs its own proof to be released.
Store an item
-
Run
putwith the item's name, kind and the origins it may be sent to:vyre vault put stripe-live --kind api-key --description "Juniper Studio Stripe" --host https://api.stripe.com -
Type the value at the hidden prompt, or pipe it on stdin. Never put a value on the command line: shell history and Claude's transcript would see it, and
putrefuses it.You should see
stored stripe-live · api-key · sent only to https://api.stripe.com
Kinds say what an item is, so the vault knows which field to hand over and what to warn about:
| Kind | Holds | Hands over |
|---|---|---|
login | username, password, one-time-code seed | password |
authenticator | a one-time-code seed on its own | the code |
passkey | a site's passkey | nothing: it signs inside the vault |
card, address, identity | payment cards, addresses, ID documents | card number; name the field |
note | text | text |
api-key, secret | one value | value |
pat | a personal access token, with its scopes and expiry | token |
oauth | client id and secret, access and refresh tokens | the first token present |
cloud | AWS keys, a service-account JSON, an Azure secret | the secret |
db-url | a database URL | url |
env-set | a .env file's variables | name the variable |
ssh-key | an SSH key | nothing: it signs through the ssh agent |
cert | a certificate and its key | certificate |
recovery-codes, wifi, license, file | backup codes, a network, a licence key, a small file | codes, password, key, content |
vyre vault put kit-github --kind pat --provider github --scope repo --scope read:org --expires 90d
vyre vault put northwind-aws --kind cloud # access key id, then the secret, hidden
vyre vault put juniper-gcp --kind cloud --from sa.json # a service account file
vyre vault put juniper-tls --kind cert --from cert.pem --key-from key.pem
vyre vault put northwind-guest --kind wifi --ssid "Northwind Guest"
The list shows each item's details: the provider, a PAT's scopes, a certificate's end date (read
from the certificate itself), a network name, how many recovery codes are left. Details never
hold a value. Watchtower flags anything expired, and anything expiring within 14 days. For a
login, add --username <name> and --totp to store a one-time-code seed (--totp needs a
terminal). For an env set, or to name the fields of any kind, use --field NAME.
If this happens
hosts must be origins such as https://api.example.com
--hosttakes a whole origin, with the scheme:--host https://api.stripe.com, not--host api.stripe.com. With--urland no--host, the URL's origin is used.
Other ways in:
vyre vault import ~/Downloads/1password-export.csv # any password manager's export, or .env files
vyre vault generate --words 5 juniper-wifi # stored, never printed, because it is named
vyre vault ssh generate deploy-key # prints only the public key
import reads the file inside Vyre, so the values never pass through Claude, and it leaves the
file alone. It reads 1Password (.1pux and CSV), Bitwarden (JSON and CSV), LastPass, Dashlane (the
zip or its CSVs), Keeper (CSV and JSON), NordPass, Proton Pass (the unencrypted zip, JSON or CSV),
Enpass, KeePass and KeePassXC (XML or CSV; export a .kdbx first), Chrome, Edge, Brave, Arc,
Firefox and Apple Passwords, and finds the format by itself. --preview shows what would come
in before anything is stored. Delete the file afterwards. generate without a name prints a password and stores
nothing.
A project's .env files come in the same way, a file or a whole folder at once:
vyre vault import ~/code/juniper-intake --preview # every .env under it, typed, never a value
vyre vault import ~/code/juniper-intake --rewrite # store them, then swap the values for references
vyre run -- npm start # reads ./.env's references; same environment as before
Each file becomes one env-set named after where it lives (juniper-intake.env,
juniper-intake-apps-web.env.local). Only secrets move: API keys, tokens, passwords, database URLs
with a password, private keys. Plain settings such as PORT or a public URL stay in the file. The
preview names each variable's type and provider (api-key openai, db-url postgres), flags a
public name holding a secret value (NEXT_PUBLIC_...=sk_live_...), and says when a file is
committed to git or missing from .gitignore. The scan skips node_modules, .git and build
folders, lists .env.example files without importing them, and follows no symlinks.
--rewrite changes a file only after every value in it is stored, writes no backup of the old
file, and leaves a file alone when its values differ from the vault's (a conflict).
In the app
Vault, Add, Bring in from another app does the same without a terminal. Pick where your passwords are now (1Password, Bitwarden, LastPass, Dashlane, Keeper, NordPass, Proton Pass, Enpass, KeePass, Apple Passwords, Chrome, Edge and the other Chromium browsers, Firefox, Safari, or a .env file), follow the one-line export steps, and choose the file. You see what would come in (new, already in the Vault, different, by kind) before anything is stored, then import with one button. Where a password in the file differs from the Vault's, the Vault's is kept unless you choose the file's, and the old one stays in that item's history. The app sends the file to your Vyre once; an assistant never sees it. Choosing a file needs Vyre on a Mac or in a browser.
Your projects, on the same page, asks Vyre for the .env files that hold keys, lists them by project (with a warning for any file git holds), and moves the ones you leave switched on into the Vault and swaps each value for a reference, under one approval.
A key pasted in chat
Paste a key into a message and Vyre catches it before the message is sent. It saves the key to the Vault
(you approve the save), and the message goes on with vault://anthropic-key in its place; the chat shows
a small "Secured in the Vault" tag. Neither the assistant nor the transcript holds the key. If the
Vault does not take it, nothing is sent. Ask the assistant to use the key and it asks for a grant, like
any other item.
Leaks and rotation
vyre vault sweep ~/code/juniper-intake --history # files and every commit; places and names only
vyre vault sweep --shell # also ~/.zsh_history and friends
vyre vault rotate kit-gitlab # a new token at GitLab, stored, the old one revoked
The sweep compares every value the vault holds with the files in a folder, and can also look through the lines each git commit added and your shell history. It also spots credentials the vault does not hold yet by their shape: a Stripe key, a GitHub token, a private key block. It says where (file, line, commit) and what (the item's name, or the kind of credential), never the value. A value in git history stays there after you delete the file, so rotate it.
rotate makes the new credential with the current one, stores it as a new version (the old one
stays in history), then revokes the old one. AWS access keys, GitLab tokens, Cloudflare API
tokens and Google Cloud service-account keys rotate by themselves. For everything else (GitHub,
OpenAI, Anthropic, Stripe and the rest) it gives the provider's page and the steps; paste the new
value with vyre vault put. The item needs its provider: --provider github on put.
Every morning after 09:00, Watchtower's findings become todos in the planner's Vault list: an
expired or soon-expiring token, a reused or old password, an item marked to rotate. Each is raised
once; more than five at once become one todo that lists them. Fixing the item closes its todo,
and a todo you dismiss stays dismissed until the reason changes. vyre call vault.remind.run
runs the pass now. Set "reminders": false under vault in config.json to turn it off.
One-time codes
The vault is an authenticator too. Every login with a seed, and every authenticator item, shows
its current code and the next one, so a code about to roll over is never a guess:
vyre vault codes # every code: current, next, seconds left
vyre vault totp juniper-google # one
vyre vault codes import --from codes.txt # Google Authenticator's export, as scanned text
To leave Google Authenticator, open it, choose Transfer accounts, then Export, and scan the QR
codes with the Vyre phone app. A large export is split across several codes;
the import waits until every part is scanned, in any order. A seed already in the vault is
recognised and skipped. Counter-based (HOTP) codes are not supported. otpauth://totp/ links
work the same way.
See what you have
vyre vault # every item: name, kind, grants; never a value
vyre vault get stripe-live # one item's metadata
vyre vault audit stripe-live # who used it, when, and whether it was allowed
In the Vyre app, Vault (/u/vault) has the sections Items, Sharing, Browsers and
Health. Add at the top right makes a login, an API key, a secret or an SSH key, or brings
them in from another app. Sharing holds what you share, what is shared with you, shared
vaults and emergency access. Health is the Watchtower: it flags weak or reused values and can
check for known breaches. A row on the Items page tells you when something needs a look.
Show, copy or fill a value yourself
Each of these is for one value, and asks you to prove presence first:
vyre vault get stripe-live --copy # to the clipboard, cleared after 90 seconds
vyre vault get juniper-portal --otp # the current one-time code
vyre vault totp juniper-portal # the same
vyre vault read vault://stripe-live/value # one field alone on stdout, for $(...) and pipes
On this Mac
The terminal asks for Touch ID (or your Mac password). After you cancel, the next request waits 30 seconds.
On a server
A terminal on the box cannot prove presence: the box has no Touch ID, and it does not accept a terminal code. There, only a passkey from the Vyre app proves you are there. Use the app, or your Mac.
- Vyre app: Copy puts the value on the clipboard of the device you are on. Reveal shows one field and masks it again after 30 seconds.
- Lumen: press Control twice, type the item's name, and choose Fill in the front app,
Copy the password or key, Copy username, Copy one-time code or Show the one-time
code. Fill types the login into the app in front through a helper; the value never returns
to Lumen (
vault.fill.native).
The Vyre app, Lumen and the browser extension open a short session with one proof. While
it lasts, reveal, copy and one-time codes do not ask again, except for cards, which ask every
time. A session ends after 10 minutes idle or 12 hours at most, when the Mac sleeps or its screen
locks, or on vyre vault lock. Set other limits in config.json under vault.lock, for example
{ "idle": "5m", "max": "8h" }. The browser extension's fill window is fixed instead: 30 minutes
from the proof (see Autofill in the browser below).
Let an agent, module or watcher use an item
A grant lets one module, or one watcher, fetch one item. Agents run as the agents module, so an
agent's setup token or API key is granted to agents (see agents).
vyre vault grant stripe-live billing # a module
vyre vault grant billing-inbox watchers --watcher juniper-invoices
vyre vault revoke billing-inbox watchers --watcher juniper-invoices
When Claude asks for a grant (vault.grant), it only creates a pending request. You approve it:
-
List what waits:
vyre vault pending.You should see
g_4f2a grant billing-inbox to watchers/juniper-invoices vyre vault approve <id> -
Approve one:
vyre vault approve g_4f2a. Or approve it from Sharing in the Vyre app, where what waits for you is listed.
Taking access away never needs presence; giving it does.
Why What happens when a module uses its grant?
At use time the module calls ctx.vault.fetch("<name>") (a watcher calls vault.fetch), and
Vyre checks the grant and hands that one value to that one caller. The internal tool is
vault.release, which no surface or model can call. Every use is written to the audit log, by
name.
Lend a login to an agent
vyre vault agent grant kit juniper-drive https://drive.juniper.example --expires 7d
vyre vault agent grants
vyre vault agent revoke <id>
The agent kit may sign in to that one site with that one login until the expiry, and never reads the login. It is a grant in your Space, the same kind as every other: the agent, the action (fill), the login, the exact origin and the expiry. Only you give it, on your own session. When Claude asks, the request waits and you approve it with vyre vault approve <id>. Taking it away needs no one, and deleting the login ends every grant on it.
Which agents can call an API credential
An agent, or your assistant, calls an API credential only through a grant in your Space: its project's linked vault, a vault shared with it, or a lease for one task. Without one the call is refused (it is not held), and the agent's Vault list shows only the credentials it holds a grant for. A read inside a grant runs at once; anything that changes something at the service still waits for your yes, grant or not. You and a thread you tagged with the credential (#name) use it by right.
A credential's older scope (projects and agents) is converted to grants once, when this version first runs: each named agent gets its credential, a scope of projects gives it to those projects, a scope of everyone gives it to the agents there are now, and your assistant keeps every credential it could reach. Each conversion is in the audit log (vault audit, action scope-converted) and announced as vault.scope-converted. After that the scope in a credential's config is ignored: change who can use it by changing the grants.
Connecting a key
A module says what it needs in its manifest (needs.credentials), and you fill each need in one
place. Voice needs a Deepgram, OpenAI or ElevenLabs key, for example, and any one of the three
will do.
-
See what every module needs, and what is still missing:
vyre vault needs.You should see
voice · speech not ready (one of deepgram, openai, elevenlabs) deepgram missing deepgram · push-to-talk words, streamed as you speak openai missing openai · push-to-talk words, transcribed on release elevenlabs missing elevenlabs · push-to-talk words and spoken replies -
Fill one:
vyre vault connect voice deepgram. It says where to get the key, then asks for it without echo. Leave out the need and it picks the first one still missing.
The key is checked against the provider (a pasted OpenAI key is refused in the Deepgram box),
saved with its kind and provider, and granted to the module, in one step that asks you to prove
you are there. A service-account key file goes in by path, vyre vault connect <module> <need> --file key.json, and then asks for the email to act as. A Google sign-in stores nothing here: it
names the sign-in to run next. vyre voice key is a shortcut for vyre vault connect voice.
A need is ready, missing, not_granted (saved but not granted), pending (Claude asked for
the grant and it waits for you) or expired. Claude can never connect a key: the value only ever
comes from your own screen.
Some modules take several accounts of one kind, such as mail: give each a label, vyre vault connect mail imap --label northwind, and each is its own item (mail-northwind).
Vault, Connections
Every account and key Vyre can act through is one connection: your Google accounts, each MCP server, each mailbox, and each key you connected. One list shows them side by side, with what each can do and which surface may use it.
vyre vault connections
vyre vault connections --can send_mail
vyre vault connections --surface agents
You should see
cn_Vq3k9x0aB2c kit at Northwind [email protected] · google-dwd · service-account
can send_mail, read_mail, calendar · capsule, chat
cn_Lm8Pz1yQw4r Juniper Studio Gmail [email protected] · mcp · oauth
can send_mail, read_mail · capsule, chat
A surface is capsule (that is Lumen), chat (Claude in a thread), agents or phone. A new connection is
granted to Lumen and chat, so "send an email" in Lumen offers every account that can
send, and Claude in a chat thread sees the same list. Agents see nothing until you grant it:
vyre vault connections grant cn_Vq3k9x0aB2c agents
vyre vault connections revoke cn_Vq3k9x0aB2c chat
vyre vault connections sync
Pick a default per capability, vault.connections.update {id, default_for: ["send_mail"]}, and
it comes first wherever an account is chosen; after it, the one used most recently. Granting asks
you to prove you are there; revoking and picking a default never do. You can also rename a connection
or change what it can do (vault.connections.update), and that survives every resync. A
connection whose key is missing or not granted to its module shows needs credential and the
vyre vault connect that fixes it. A row someone changed behind the vault's back fails its check
and is granted to nothing until you grant it again.
Your Google accounts and MCP servers appear on their own: the vault reads them each time one is added, changed or removed.
For module authors. Register each account with
vault.connections.register {ref, provider, account, auth, label?, capabilities? or tools?, items?, use?}; the source is your module's name. Before acting for a caller, askvault.connections.allowed {id, caller}and refuse unless it saysallowed: true. When a key is missing, answer with{code: "needs_credential", message, detail: {module, need, account?}}(core/modules/needs-credential.js). The vault emitsvault.connection-added,vault.connection-removedandvault.connection-changed.
Use an item in a script
Scripts outside Vyre run under vyre vault run, which puts the values into one child process's
environment and scrubs them from its output:
vyre vault run STRIPE_KEY=stripe-live -- npm run charge
vyre vault run --env-file .env.vyre -- node server.js # KEY=vault://item/field lines
vyre vault inject -i config.tpl -o config.json # {{ vault://item/field }}; Vyre writes the file, 0600
An item before -- is <name>, <name>.<field>, VAR=<name> or VAR=<name>.<field>; without VAR=, the
variable is the name in capitals (stripe-live becomes STRIPE_LIVE). A value the child prints
shows as <concealed by vyre>. These need presence, so Claude's own shell cannot use them to read
a value.
Share with another person
A pass shares items with another person's Vyre. In this example you share with Dana, who runs her own Vyre.
-
Swap cards. Send Dana the output of
vyre vault card, and add hers:vyre vault people add <her card> --name dana -
Compare the four safety words out of band (on a call, in person). You both run
vyre vault fingerprint danaand should see the same words. Then:vyre vault people verify dana <fingerprint> -
Share:
vyre vault share stripe-live --with dana --expires 30dIt prints a ticket. The ticket carries no secret; send it to Dana.
-
Dana accepts it with
vyre vault pass accept <ticket>.
A pass is one of two kinds:
- Relayed (the default): the value never leaves your box. Dana's calls go through your Vyre
with
vyre vault relay(vault.relay), your Vyre adds the value, and revoking ends her access at once.--host,--methodand--pathonvyre vault pass createnarrow what her calls may reach. - Sealed (
--sealed): Dana gets an encrypted copy, for offline use. Revoking a sealed pass means rotating the credential.
If this happens
stripe-live has no hosts it may be sent to, so it cannot be relayed
A relayed pass sends the value only to the item's hosts. Store the item again with
--host https://api.stripe.com, or share it--sealed.
To end sharing:
vyre vault pass list
vyre vault pass revoke <id>
vyre vault offboard dana # revoke every pass she holds and list what must be rotated
For a team, vyre vault vaults create <name> makes a shared vault and
vyre vault members invite <vault> <person> adds people to it. Its items appear as
<vault>/<item>.
In the app, Vault, Sharing, Shared vaults does the same: New shared vault, Invite (pick a role, then send the person the code it makes), Manage to change a role or take someone out, and Change the keys. Only an admin sees those buttons. Accept a share takes an invite or a pass someone sent you. Taking someone out names the items to replace, because they could read them.
A paired phone can do the same (the app's screens for it come with the Vault screens): it makes a shared vault, lists and syncs them with no question, and asks for your yes (the same one as for showing a secret) before it invites someone, changes a role, removes a member or changes the vault's key. An assistant or an outside agent can read the list and pull changes, and can do nothing else here.
Used by
Open any credential and it lists everything that uses it, in one place: the Vyre modules you gave it
to, the Connections that hold it, the agents it was lent to and where, the sites that were granted it,
the apps made with it, the Flows that name it, and the records it is linked to. Each line says what a
new value does to it. A site's server and an installed app restart with the new value when you rotate
the key (a burst of changes is one restart); a Connection, a module, a Flow and an agent read it the
next time they use it; a site that only uses the key to build reads it at the next build. The list holds
names and times, never a value. Ask for it from the terminal with vyre call vault.used-by '{"item":"deepgram"}'.
A login linked to a client
Link a login to the client, matter or project it belongs to (the portal login for this client) and
every use of it shows on that record's timeline: "portal-login was used to sign in by the agent
kit". Only the name and the time appear. The login itself is never on the record, the link or the
timeline, and a link gives nobody access to anything; it only says which record the login is for.
The link is part of the record itself (its "Logins and keys it uses" field), so it travels with the record. A login that is deleted drops out of every answer. For now you link from the terminal,
vyre call vault.link '{"item":"portal-login","to":"vyre://.../client/..."}'; the app's own
screen for it comes with the Vault screens.
Keys for a published site
A site or app you publish gets the keys it needs from the Vault, one at a time, and only the ones you give it. You put a key in the Vault once (say a Deepgram key), then give it to each deployment that needs it from that deployment's secrets. Two deployments and your chat's transcripts can use the same key: each has its own permission, taking it away from one leaves the others, and changing the key in the Vault changes it for all of them at the next build. Deleting the key from the Vault takes it away from every deployment. A key never appears in a site's files, its build log or the page; the Vault's log shows which deployment used which key and when.
Emergency access
Emergency access lets someone you trust open your items if something happens to you. They have to ask, and then wait. You can stop it any time before the wait runs out. In this example Juno is Alex's emergency contact.
-
Swap cards and verify fingerprints, as for a pass. Emergency access needs a verified card: a card that was only pinned, or whose key changed, is refused.
-
Alex keeps emergency access for Juno:
vyre vault emergency add juno --wait 7dThe wait is 1 to 30 days (7 by default). Without
--item, it covers every item except ssh keys and passkeys. Alex's Vyre seals those items to Juno's key and keeps them in escrow. Neither Alex's box nor Juno can open them alone. -
When Juno needs them, Juno runs
vyre vault emergency request alex. Alex gets a todo in the Vault list of the planner: "juno asked for emergency access: it opens on <date> unless you deny it". -
Alex can stop it with
vyre vault emergency deny juno. Juno may ask again, and the wait starts again. -
After the wait,
vyre vault emergency status alexon Juno's Vyre takes the items in, the same way a sealed pass does.
The escrow is a snapshot. It is rebuilt when you unlock your personal vault, at most once a day,
and vyre vault emergency refresh rebuilds it now. vyre vault emergency list shows each
contact, the wait and where a request stands. vyre vault emergency remove juno ends it and
deletes the escrow. Once items are released, Juno holds copies, so rotate them if that was not
what you wanted.
Autofill in the browser
The Chrome extension in modules/vault-extension/ fills logins from your Vault.
- Set
vault.fillinconfig.json, for example{ "host": "127.0.0.1", "port": 7788 }(the extension looks athttp://127.0.0.1:7788unless you change it), and restart Vyre (vyre down, thenvyre up). - In
chrome://extensions(Chrome, Arc, Edge, Brave), turn on Developer mode and Load unpacked that folder. In Firefox 121 or later, openabout:debugging, choose Load Temporary Add-on and pick itsmanifest.json. - Set the passphrase the extension asks for:
vyre vault unlock-passphrase. - Pair it:
vyre vault pairprints an 8-character code that works once, for 5 minutes. Type it into the extension.
On a login page, unlock with the passphrase (or Touch ID through Lumen) and choose Fill.
Only logins whose hosts include the page's exact origin (scheme, host and port) are offered, so a
lookalike domain gets nothing. An unlock lasts 30 minutes from the proof, and filling does not
extend it; vault.fill.window in config.json (minutes, 1 to 30) makes it shorter. The same
extension loads in Firefox; see modules/vault-extension/README.md.
vyre vault devices lists paired browsers; vyre vault devices revoke <id> ends one at once. The
design is in ADR 0010.
Cards and addresses
In a checkout or address form, the extension offers your cards and addresses as it offers logins; the popup lists them too. They are not tied to a site. A card asks every time by default: fill it within a minute of unlocking, or unlock again. The PIN is never filled. Card fields inside a payment provider's own frame (Stripe Elements and the like) are not filled yet.
Passkeys
With the extension paired, a site that offers a passkey asks Vyre first: "Save a passkey for
juniper.test in Vyre?" when you make one, and "Sign in to juniper.test as alex with Vyre?" when you
use one. Continue works inside your unlock window. Use another device hands the request to
the browser's own authenticator (a phone, a security key, iCloud Keychain). Passkeys are items of
kind passkey; their private keys stay in the vault and only sign, so nothing can show, copy or
hand one out. The popup's "Use Vyre for passkeys" turns it off. Firefox needs version 128.
Autofill on the phone is not built yet.
Your personal vault, and getting it back
vyre vault account create # sets the password; prints your Secret Key once
vyre vault kit # a recovery kit: a one-time page on this machine
vyre vault account enroll-touchid
vyre vault account lock
The Secret Key is printed once and not written to any file. Keep the recovery kit. Your agents keep what is granted to them while your personal vault is locked.
vyre vault backup <file> writes the whole vault sealed to a passphrase of its own, and
vyre vault restore <file> reads one back.
If this happens
The vault is locked (exit code 4)
With the passphrase keystore, run
vyre vault unlock. For your personal vault, runvyre vault account unlock(add--touchidonce you enrolled it), or unlock in the Vyre app. Unlocking with Touch ID meets thepresence_requiredproblem above. Unlocking with the password asks once, for the password itself. After five wrong passwords in a row, Vyre refuses every try for 30 seconds, then 60, doubling up to 15 minutes, and a right password starts the count over. Touch ID unlock never passes through that count, so it still works during the wait.
Which surface does what
| Task | Terminal | Vyre app | Lumen | Claude |
|---|---|---|---|---|
| Add an item | vyre vault put, import | Add an item | vault.import (a file path), never a value | |
| List items | vyre vault | /u/vault | type a name | vault.list (names only) |
| Copy, reveal, code | get --copy, --reveal, --otp, totp | Copy, Reveal | Copy, Show the code | never |
| Fill a login | Fill in the front app | never | ||
| Grant | vyre vault grant, approve | Passes | vault.grant (waits as pending) | |
| Share | vyre vault share | share sheet | vault.pass.create (waits for approval) | |
| Offboard | vyre vault offboard | offboard sheet | vault.offboard (asks you for presence) |
Inside a Claude Code session, the use-the-vault skill tells Claude these rules.
What it will not do
- Show a value to Claude, an agent, a log or an event.
- Take a value from Claude.
vault.putrefuses it. - Let Claude approve its own grant or pass.
- Fill a login on a page whose origin is not one of the item's hosts.
- Hand out a passkey's private key. A passkey only signs inside the vault.