The Secret Vault

The Vault stores your API keys encrypted at rest with AES-256-GCM, referenced by name not value. Learn what it holds, how keys resolve at runtime, and how to

What you'll learn

  • What the Vault is, what it stores, and what it deliberately does not store.
  • The difference between what you see in the UI (key names) and what the database holds (ciphertext).
  • How to rotate a key once and have every connection pick it up.

The concept: store the value once, reference it by name

m18t talks to outside services on your behalf — AI providers, social platforms, your headless CMS. To do that it needs real credentials: an OpenAI key, a Meta access token, a Strapi API token. Those are sensitive. A token with write access to your CMS or your Facebook Page is, in the wrong hands, a way to vandalise your brand.

So m18t never keeps those raw values lying around. It keeps them in the Vault: encrypted at rest with AES-256-GCM, decrypted only for the instant a call is made, and referenced everywhere else by a name you choose. You see OPENAI_API_KEY; the database holds ciphertext.

You reach the Vault at Business Settings → Connections (/studio/business/connections), on the Vault tab. The tab carries its own note: "Where your raw keys live, encrypted at rest with AES-256-GCM. Connections reference these by name. Most workspaces never need to touch this directly — it's here for rotations and audits." That last line is the honest framing: in normal use you add keys through the connection wizard, not here. The Vault tab is the place to rotate and audit them later.

What's actually in the Vault — and what isn't

The Vault holds credentials for AI providers (OpenAI, Google/Gemini, Anthropic), social APIs (Meta Graph), CMS tokens (Strapi), analytics keys, and SMTP passwords. Those all use the encrypted Vault path.

Storage credentials are the exception today. m18t's object storage is configured at the platform level right now, not per-workspace in the Vault — a deliberate temporary bypass while per-workspace BYOK storage is built as its own beta feature. Workspace isolation for storage is enforced at the bucket level (each workspace gets its own isolated bucket), not via per-workspace credentials. So if you're looking for "where do I put my S3 keys" — for most users that's nowhere; see Where Your Files Live for the full picture.

How a key moves through the system

When you save a key, it follows a fixed path:

  1. In memory, briefly. You paste the raw value into the form and submit. It travels to the server, lives in memory long enough to be encrypted, and is not written to logs or a temp cache.
  2. Encrypted at rest. Before anything is persisted, the raw value is encrypted with AES-256-GCM using a server-side master key. The encrypted secret is stored in your encrypted secret vault — not as plain text.
  3. Resolved at runtime. When an action needs the credential — publishing to Meta, generating an image — the server resolves the reference, decrypts the value in memory, makes the call, and drops the decrypted value. The raw key is never returned to your browser and never logged.

The resolution is three-tier. A connection's token field can hold vault:KEY_NAME (look it up in the workspace Vault), env:VAR_NAME (fall back to a platform environment variable — legacy path), or a literal value (used as-is, not recommended). New connections use vault:.

Adding and naming keys

You'll usually add a key without visiting the Vault tab at all. In the connection wizard, the Authentication step lets you pick an existing Vault key or add a new one inline — name it, paste the value, and it's saved as vault:YOUR_KEY_NAME and selected for that connection in one move.

If you do add a key directly on the Vault tab, the Add Key button opens a small form with three fields:

  • Key — the reference name. The convention is UPPERCASE_WITH_UNDERSCORES, e.g. OPENAI_API_KEY or CMS_PROD_API_TOKEN.
  • Value — the raw secret. This is the only time you paste it; afterward the UI shows only the name.
  • Category — one of AI, CMS, Social, Storage, or General, for organisation.

The Key name is stored in plain text on purpose — it's a label, not a secret. The Value is what gets encrypted.

Rotating a key

This is where the name-not-value design earns its keep. Say an OpenAI key is compromised, and ten brands across your workspace reference it as vault:OPENAI_API_KEY. You do not edit ten connections:

  1. Revoke the old key in OpenAI's dashboard and generate a new one.
  2. On the Vault tab, find OPENAI_API_KEY and use its Rotate action.
  3. Paste the new value and save.

Every connection that references vault:OPENAI_API_KEY resolves the new value on its next call. One update, whole workspace. The Vault tab also shows, per key, how many connections use it ("Used by 3 connections"), so you can see the blast radius before you rotate.

A note on what "secure" means here

AES-256-GCM at rest is real and live for every Vault secret. What that protects against is a dumped database file: an attacker who got the underlying database would see ciphertext, not your keys. It is not a claim that no precaution is ever needed on your side — protect your own provider accounts, set spending caps, and revoke keys you suspect. The Vault makes m18t a safe place to store the credential; the rest of the chain is still yours to mind.

FAQ

Can I see a key's raw value after I save it? No. The UI shows only the reference name. The raw value is encrypted and never returned to the browser. If you've lost the original, generate a new one at the provider and rotate.

Do I have to use the Vault tab to add keys? No — most of the time you'll add a key inline while creating a connection. The Vault tab is for rotating and auditing existing keys.

Where do storage (S3/MinIO) credentials go? Not the Vault, today. Storage is configured at the platform level as a temporary measure; isolation is per-bucket. See Where Your Files Live.

My connection says "vault key missing" — what happened? The connection references a vault: name that has no stored value (often after a brand copy, or if a key was removed). Re-add the key under that exact name on the Vault tab, or edit the connection to point at an existing key.

If I rotate a key, do I have to republish or reconnect anything? No. Connections reference the name, not the value, so the next call uses the new value automatically.

What's next

Was this article helpful?