Moatgator Vault
One place for the secrets of your backend, your CI and your mobile app
Put an mg:// reference where the value used to be. The CLI, GitHub Actions and the mobile SDK resolve it when they run, and your app receives a secret only on a device that passed Attest.
Included from the Startup plan.
$ moatgator secrets run --env-file .env.tpl -- npm start$ moatgator secrets inject -i .env.tpl -o .env$ moatgator secrets get mg://api/prod/DATABASE_URLmg:// references
Commit the reference, not the value
A reference names a project, an environment and a secret, as in mg://api/prod/DATABASE_URL. It is safe to keep in Git: only an identity with access turns it into a value.
01
A .env.tpl in your repository
Keep one template with references. moatgator secrets inject writes the .env with 0600 permissions and does not overwrite an existing file without --force.
.env.tplExample # .env.tpl: safe to commitDATABASE_URL=mg://api/prod/DATABASE_URLSTRIPE_KEY=mg://api/prod/STRIPE_KEYSENTRY_DSN=mg://api/prod/SENTRY_DSN02
moatgator secrets run
Runs your command with the secrets as environment variables and hides their values in the command output. moatgator secrets get reads a single reference.
terminalExample $ moatgator secrets run --env-file .env.tpl -- npm start$ moatgator secrets inject -i .env.tpl -o .env$ moatgator secrets get mg://api/prod/DATABASE_URL03
The same reference in the app
In the Android SDK, Moatgator.vault.get("mg://mobile/prod/PARTNER_KEY") reads the environment linked to the app in the console. The value never ships in the APK.
KotlinExample // Android (Kotlin), off the main threadMoatgator.startSession(playIntegrityProvider)val key = Moatgator.vault.get("mg://mobile/prod/PARTNER_KEY")
Projects, environments and versions
Projects and environments
Each project starts with dev, staging and prod. Add your own environments when you need them.
Inheritance and overrides
An environment can inherit from another, up to three levels. A secret with the same name overrides the inherited one.
Protected environments
prod starts protected: only owners and admins can read its values or write to it.
Versions and rollback
Every change creates a version with history. A rollback creates a new version, so history is never rewritten.
Immediate revocation
Revoke a secret or a service token and the next read is refused, without waiting for an expiry date.
Roles
Owner, admin, developer and reader roles decide who sees values and who changes them.
Only on attested devices
The same secret, delivered to your mobile app only on a device that passed Attest
Secrets managers usually serve servers, developers and CI. The Vault also serves the app in your users' hands: the SDK asks at run time, the API checks the device's Attest (Play Integrity or App Attest, plus the Moatgator RASP signals) and sends the value encrypted for an ephemeral key of that session. Nothing goes into the binary.
The SDK keeps the value in memory only, never on disk or in logs. mg:// references are available in the Android SDK.
Policies per secret
- Minimum verdictChoose the lowest Attest verdict that may receive each secret.
- Platform attestation requiredRequire a platform attestation result, not only the signals of the SDK itself.
- Maximum attestation ageRefuse the secret when the device's attestation is older than you allow.
CI and servers
No long-lived token stored in your CI
The GitHub Action moatgator-hq/github-action/vault exchanges the job's OIDC token for a read token that lasts 15 minutes. Pull requests never receive a token. Where OIDC is not available, use a service token.
- Service tokens (mgvt_…) are read-only and bound to one project and the environments you choose.
- Expiry is required: 90 days by default, one year at most.
- Values are masked in the job log and never become step outputs.
- A reference that does not resolve fails the step without exporting anything.
permissions: { contents: read, id-token: write }steps: - uses: moatgator-hq/github-action/vault@v1 with: project-id: vpj_… secrets: | DATABASE_URL=mg://api/prod/DATABASE_URL - run: ./deploy.sh # $DATABASE_URL, *** in the logSync and rotation
Push secrets to where you deploy, and rotate them on a schedule
A sync keeps an environment, with inheritance, copied to GitHub Actions secrets, Railway or Vercel. It runs when you create it and again after every change to that environment or to an environment it inherits from.
GitHub Actions secrets
Sync to a repository or to a GitHub environment. Each value is encrypted with the repository's public key before it leaves Moatgator.
Railway
Sync to the variables of a Railway project and environment, or of a single service.
Vercel
Sync to the production, preview or development variables of a Vercel project, stored as encrypted variables.
Explicit permission and status
You confirm each destination and give it a token for that destination only, stored encrypted. Each sync shows when it last ran, how many secrets it wrote and any error.
Scheduled rotation
- A new random value on scheduleFor secrets only your company uses, such as HMAC keys and session secrets: Moatgator generates a new value, creates a version and runs the syncs.
- A reminder for keys from other providersFor a key issued by another service, owners and admins get an email when it is due, and the console shows the rotation as overdue until a new value is saved.
A sync only writes to the destination, and deletes there only the secrets it wrote itself. Deleting a sync leaves the destination as it is.
Encrypted per organization, audited on every read
Envelope encryption per tenant
Each organization has its own key, wrapped by a master key.
Ciphertext bound to its place
Each ciphertext is bound to its project, environment, name and version, so it cannot be moved to another secret.
Values stay out of logs
Secret values are never written to our logs, and the CLI and the Action hide them in your output.
Audit trail of every read
For every read: who read it, from where, which version and the result.
Compare
Moatgator Vault, 1Password and Doppler
1Password and Doppler are established secrets managers, and both do much of what the Vault does. The table shows where each one stands, with a public source and the date we checked it for every cell about them. The Vault is not a password manager for people: it focuses on apps, CI and mobile devices.
| Capability | Moatgator Vault | 1Password | Doppler |
|---|---|---|---|
| References in place of values | mg://project/environment/NAME, also in the mobile SDK | 1 op://vault/item/field | Partial23 ${…} references inside Doppler; {{.NAME}} templates for files |
| Run a command with secrets as environment variables | values hidden in the output | 4 op run, values masked in the output by default | 56 doppler run; output masking not documented for the CLI |
| Render a file from a template | file written with 0600 permissions | 7 op inject | 3 secrets substitute and --mount |
| Environments with inheritance | up to 3 levels, override by name | Partial8 Environments exist, independent of each other | 910 branch configs inherit from the root config; config inheritance on Team and Enterprise |
| Version history and rollback | rollback creates a new version | 11 item history and restore | 12 rollback from the logs |
| Scoped machine tokens with expiry | read-only, per project and environment, expiry required | 1314 service accounts with per-vault permissions and optional expiry | 15 service tokens per config, optional expiry |
| Immediate token revocation | 16 | 15 | |
| CI with OIDC, without a stored token | GitHub Actions, 15-minute token | Partial1718 load-secrets-action uses a stored token; Credential Broker with OIDC in public preview | 196 service account identities, Team and Enterprise plans |
| Sync to GitHub Actions, Railway and Vercel | after every change; writes only, deletes only what it wrote | Partial820 Environments sync to AWS Secrets Manager (beta); GitHub, Railway and Vercel not found | 2122 GitHub, Vercel and Railway integrations push secrets automatically |
| Scheduled rotation | Partial new random value for secrets you own; email reminder for third-party keys | Not found in public docs2316 service account tokens rotate by hand; scheduled rotation of stored secrets not found | 24 automatic rotation of supported services, such as databases, on Team and Enterprise |
| Roles and protected production | owner, admin, developer and reader; prod protected | 258 vault and Environment permissions | 26 project and environment roles |
| Audit of every secret read | who, from where, version and result | 27 usage reports on 1Password Business | Partial28 access log keeps the first and the latest read per actor |
| Delivery to a mobile app only on an attested device | Attest plus RASP, encrypted per session | Not found in public docs2930 not found in the SDK and Connect docs | Not found in public docs3121 not found in the SDK and integration docs |
Where 1Password is strong
Sources
- 1. 1Password CLI — Secret references · checked on
- 2. Doppler — Secrets (referencing) · checked on
- 3. Doppler — Secret injection with templates · checked on
- 4. 1Password CLI — op run · checked on
- 5. Doppler — Accessing secrets (run, --mount) · checked on
- 6. Doppler — GitHub OIDC examples · checked on
- 7. 1Password — Load secrets into config files (op inject) · checked on
- 8. 1Password Environments · checked on
- 9. Doppler — Branch configs · checked on
- 10. Doppler — Config inheritance · checked on
- 11. 1Password — View and restore previous versions of items · checked on
- 12. Doppler — Versioning · checked on
- 13. 1Password CLI — op service-account · checked on
- 14. 1Password CLI — op connect · checked on
- 15. Doppler — Service tokens · checked on
- 16. 1Password — Manage service accounts · checked on
- 17. 1Password — GitHub Actions (load-secrets-action) · checked on
- 18. 1Password Credential Broker — GitHub Actions (public preview) · checked on
- 19. Doppler — Service account identities (OIDC) · checked on
- 20. 1Password — Sync Environments to AWS Secrets Manager (beta) · checked on
- 21. Doppler — Integrations · checked on
- 22. Doppler — GitHub Actions integration · checked on
- 23. 1Password Secrets Automation · checked on
- 24. Doppler — Secrets rotation · checked on
- 25. 1Password — Create, share, and manage vaults · checked on
- 26. Doppler — Project permissions · checked on
- 27. 1Password — Reports (usage reports) · checked on
- 28. Doppler — Access logs · checked on
- 29. 1Password SDKs · checked on
- 30. 1Password Connect · checked on
- 31. Doppler — Future SDKs and integration roadmap · checked on
- 32. 1Password — About the 1Password security model · checked on
- 33. 1Password — About your Secret Key · checked on
- 34. Doppler — Security fact sheet · checked on
- 35. Doppler — Pricing · checked on
1Password and Doppler are trademarks of their owners, named only to identify the products compared. What we say about them comes from their public documentation on the date shown. “Not found” means we did not find it in the pages cited, not that the product lacks it. If something changed, write to us and we will correct it.
Plans
The Vault is included in the Startup, Scale and Enterprise plans.
| Plan | Projects per organization | Secrets per environment |
|---|---|---|
| Startup | 5 | 100 |
| Scale | 50 | 500 |
| Enterprise | 200 | 1,000 |
Frequently asked questions
Do I need to change my code to use the Vault?
Not on servers and CI: your code keeps reading environment variables, and you start the process with moatgator secrets run or the GitHub Action. In the Android app, call Moatgator.vault.get with the reference.
Can someone who has my APK read a Vault secret?
The value is not in the APK. The API sends it only to a device that passed Attest under the secret's policy, encrypted for that session, and the SDK keeps it in memory only. A device can still be compromised after it passed, so keep server-side checks for anything that moves money.
What happens if a service token leaks?
Revoke it in the console and the next request is refused. Service tokens are read-only, limited to one project and the environments you chose, and expire in 90 days by default.
Does the Vault replace 1Password or Doppler?
Not necessarily. If you already use one of them for servers and CI, it can stay. The Vault adds delivery to your mobile app on attested devices, and can cover servers and CI too if you prefer one tool.
Which plans include the Vault?
Startup, Scale and Enterprise. Projects per organization: 5, 50 and 200. Secrets per environment: 100, 500 and 1,000.
Start with one secret
Create a project, add a secret and resolve it from the CLI, your CI or your app.