🛡️ @trap_stevo/aegis
The Shield of Secrets.
An encrypted, attestable, process-safe credentials vault with bootstrap, admin passkeys, developer enrollment, and enum-based storage — designed to safeguard credentials while staying effortless to use across machines, CI/CD pipelines, and runtime apps.
🚀 Features
- 🧱 Machine-Bound Encryption – Secrets are sealed to your machine’s identity
- 🧩 Bootstrap & Admin Flow – Securely initialize, bootstrap, and manage passkeys
- 👥 Developer Enrollment – Invite and register developers with time-limited codes
- 🔑 Grant System – Enforce which scripts, tokens, or modules can read secrets
- ⚙️ Enum-Based Storage – Portable secure paths (PROJECT, USER, SYSTEM, TEMP)
- 🔒 Vault API & Client API – Use high-level or low-level interfaces as needed
- 🧰 CLI Ready – Initialize, bootstrap, set, or read secrets interactively
- 💨 process.env Integration – Optional runtime injector for dynamic secret binding
⚙️ System Requirements
| Node.js | ≥ 18.x |
| npm | ≥ 9.x |
| OS | Windows, macOS, Linux |
Entry Points
const { createAegis, createAegisEnv, inject } = require("@trap_stevo/aegis");
🧠 Core Concepts
| Aegis API | Full administrative access (bootstrap, manage, rotate, invite) |
| Aegis Env API | Lightweight, read-only runtime access for apps |
| Inject API | Auto-injects vault secrets into process.env dynamically |
⚙️ Configuration
createAegis(options)
| storagePath | string | required | Base directory or enum (PROJECT, USER, SYSTEM, TEMP) |
| namespace | string | "vault" | Folder name under storage path |
| offset | string | "machine-v1" | Salted key derivation offset |
| lockprint | string | null | Custom fingerprint override |
| lockprintOptions | object | {} | Fingerprint file and size options |
| shardCount | number | 32 | Internal vault shard count |
createAegisEnv(options)
| storagePath | string | required | Same enum or path as createVault |
| namespace | string | "vault" | Name of vault directory |
| offset | string | "machine-v1" | Salt key for machine binding |
| lockprint | string | null | Optional fingerprint override |
| lockprintOptions | object | {} | Lockprint configuration |
| AEGIS_GRANTS_MODE | string | "strict" | Env override for dev mode ("permissive") |
inject(options)
| storagePath | string | required | Vault root path or enum |
| namespace | string | "vault" | Vault directory |
| offset | string | "machine-v1" | Key offset |
| lockprint | string | null | Custom fingerprint |
| preload | boolean | true | Preload all secrets to process.env |
| cacheSeconds | number | 0 | Cache TTL for injected secrets |
| enforceNoPlainOverwrite | boolean | true | Prevent overwriting existing env vars |
🧰 API Specifications
🔐 Aegis Methods
| init() | Initialize the vault and create bootstrap token | ✅ |
| bootstrapAdmin(adminID, token, passphrase) | Secure the vault and establish admin credentials | ✅ |
| addDeveloper(devID, tempPass, adminID, adminPass) | Create a new developer entry | ✅ |
| createInvite(devID, adminID, adminPass, opts) | Generate one-time invite codes | ✅ |
| addDevWithInvite(devID, inviteCode, adminID, adminPass) | Add developer directly using an invite | ✅ |
| claimInvite(devID, code, newPassphrase) | Developer claims an invite and sets password | ✅ |
| changePassphrase(devID, oldPass, newPass) | Change developer password | ✅ |
| removeDeveloper(devID, adminID, adminPass) | Remove developer access | ✅ |
| setSecret(name, value, adminID, adminPass) | Store a secret securely | ✅ |
| importSecrets(object, adminID, adminPass, opts) | Bulk import secrets | ✅ |
| getSecret(name, opts) | Retrieve a secret by key | ✅ |
| listNames() | List all stored secret names | ✅ |
| deleteSecret(name, adminID, adminPass) | Delete a secret | ✅ |
| addGrant(appID, grant, adminID, adminPass) | Add a new grant rule | ✅ |
| removeGrant(appID, adminID, adminPass) | Remove a grant rule | ✅ |
🧩 Aegis Env Methods
| get(name, { appID, appCWD }) | Retrieve secret (grant enforced) | ✅ |
| getSync(name, { appID, appCWD }) | Retrieve secret synchronously | ❌ |
Supported Grant Types
- file_hash – pin to file SHA-256 hash
- token – signed token file verification
- plugin – external module-based verifier
🌐 Aegis Inject API
| injectKey(name) | Inject one secret into process.env | ✅ |
| refresh() | Clear cache and reload all injected values | ✅ |
| list() | List all injected secret names | ✅ |
🔑 Grant Types
| file_hash | Locks access to a specific file checksum | CLI or local scripts |
| token | Validates signed token file (ed25519) | CI/CD, build pipelines |
| plugin | Loads verifier module dynamically | Custom policies or SDKs |
🧩 Example Grant
await vault.addGrant("demo-app", {
type : "file_hash",
path : "./aegisClientDemo.js",
sha256 : "abc123..."
}, "admin:local", "admin-pass");
💻 CLI Command Reference
aegis init | Initialize a new vault and print bootstrap token |
aegis bootstrap-admin <adminID> | Secure vault and create admin credentials |
aegis add-dev <devID> <adminID> | Register a new developer |
aegis create-invite <devID> <adminID> | Create a one-time invite code |
aegis claim-invite <devID> <code> | Developer claims an invite and sets password |
aegis set <key> <value> <adminID> | Store a new secret |
aegis get <key> | Read a secret value |
aegis list | List all stored secret names |
aegis delete <key> | Delete a secret |
aegis add-grant <appID> | Add a file_hash, token, or plugin grant |
aegis remove-grant <appID> | Remove an existing grant |
aegis info | Display vault configuration summary |
🧪 Example CLI Workflow
npm run start-aegis-init
npm run start-aegis-set -- --grant
npm run start-aegis-client
Re-run npm run start-aegis-set -- --grant whenever your file hash changes to refresh the grant.
📦 Installation
npm install @trap_stevo/aegis
🏁 Quick Start
Initialize and Bootstrap
npx aegis init
npx aegis bootstrap-admin <adminDevID>
Add Developer
npx aegis add-dev <devID> <adminDevID>
Set Secret
npx aegis set API_KEY my-secret-value <adminDevID>
Read Secret Programmatically
const { createAegisEnv } = require("@trap_stevo/aegis");
(async () => {
const env = createAegisEnv({ storagePath : "PROJECT", namespace : "vault" });
const key = await env.get("API_KEY", { appID : "demo-app" });
console.log("API Key:", key);
})();
🧭Initializing Aegis via Code
Initializes the vault and bootstraps an admin account.
"use strict";
const { createAegis } = require("@trap_stevo/aegis");
const path = require("path");
const STORAGE = path.resolve(__dirname, ".aegis_store");
const NAMESPACE = "vault";
const ADMIN_ID = process.env.AEGIS_ADMIN_ID || "admin:local";
const ADMIN_PASS= process.env.AEGIS_ADMIN_PASS|| "aegis";
(async () => {
const vault = createAegis({ storagePath : STORAGE, namespace : NAMESPACE });
const token = vault.init();
console.log("[init] bootstrap token:", token);
vault.bootstrapAdmin(ADMIN_ID, token, ADMIN_PASS);
console.log("[init] admin bootstrapped:", ADMIN_ID);
console.log(`[init] vault ready at ${path.join(STORAGE, NAMESPACE)}`);
})();
🧱 Setting Secrets via Code
Sets secrets into the vault and optionally registers a grant (using --grant).
"use strict";
const { createAegis } = require("@trap_stevo/aegis");
const crypto = require("crypto");
const path = require("path");
const fs = require("fs");
const STORAGE = path.resolve(__dirname, ".aegis_store");
const NAMESPACE = "vault";
const ADMIN_ID = process.env.AEGIS_ADMIN_ID || "admin:local";
const ADMIN_PASS = process.env.AEGIS_ADMIN_PASS || "aegis";
const ADD_GRANT = process.argv.includes("--grant") || process.env.AEGIS_ADD_GRANT === "1";
const APP_ID = process.env.AEGIS_APP_ID || "demo-app";
const READER_REL = process.env.AEGIS_READER_REL || "./aegisClientDemo.js";
function sha256FileHex(p)
{
const h = crypto.createHash("sha256");
h.update(fs.readFileSync(p));
return h.digest("hex");
};
(async () => {
const vault = createAegis({ storagePath: STORAGE, namespace: NAMESPACE });
await vault.setSecret("SERVICE_API_KEY", "sk_live_123", ADMIN_ID, ADMIN_PASS);
await vault.setSecret("DB_PASSWORD", "p@ssw0rd!", ADMIN_ID, ADMIN_PASS);
await vault.importSecrets({ MAILGUN_KEY: "mg_abc", S3_SECRET: "s3_xyz" }, ADMIN_ID, ADMIN_PASS, { overwrite: false });
console.log("[set] secrets written.");
if (ADD_GRANT)
{
const fullReader = path.resolve(__dirname, READER_REL);
const readerHash = sha256FileHex(fullReader);
await vault.addGrant(
APP_ID,
{ type : "file_hash", path : READER_REL, sha256 : readerHash },
ADMIN_ID,
ADMIN_PASS
);
console.log(`[grant] Added file_hash grant for appID=${APP_ID}`);
console.log(`[grant] path=${READER_REL}`);
console.log(`[grant] sha256=${readerHash}`);
console.log("[grant] Vault now in STRICT mode (since at least one grant exists).");
}
})();
📖 Accessing Secrets Directly through Aegis
Reads secrets directly from the vault (admin access).
"use strict";
const { createAegis } = require("@trap_stevo/aegis");
const path = require("path");
const STORAGE = path.resolve(__dirname, ".aegis_store");
const NAMESPACE = "vault";
const ADMIN_ID = process.env.AEGIS_ADMIN_ID || "admin:local";
const ADMIN_PASS = process.env.AEGIS_ADMIN_PASS || "aegis";
(async () => {
const vault = createAegis({ storagePath: STORAGE, namespace: NAMESPACE });
try
{
const apiKey = await vault.getSecret("SERVICE_API_KEY", { devID : ADMIN_ID, passphrase : ADMIN_PASS });
const dbPass = vault.getSecretSync("DB_PASSWORD", { devID : ADMIN_ID, passphrase : ADMIN_PASS });
const names = await vault.listNames();
console.log("SERVICE_API_KEY =", apiKey);
console.log("DB_PASSWORD =", dbPass);
console.log("All keys =", names);
}
catch (error)
{
console.error("[Vault] read failed ~", error.message);
process.exitCode = 1;
}
})();
🔐 Accessing Secrets through Client
Reads secrets through the Aegis Env API, validating with grant enforcement.
"use strict";
const { createAegisEnv } = require("@trap_stevo/aegis");
const path = require("path");
const STORAGE = path.resolve(__dirname, ".aegis_store");
const NAMESPACE = "vault";
const APP_ID = process.env.AEGIS_APP_ID || "demo-app";
(async () => {
const env = createAegisEnv({ storagePath : STORAGE, namespace : NAMESPACE });
try
{
const apiKey = await env.get("SERVICE_API_KEY", { appID : APP_ID, appCWD : __dirname });
console.log("SERVICE_API_KEY =", apiKey);
const dbPass = env.getSync("DB_PASSWORD", { appID : APP_ID, appCWD : __dirname });
console.log("DB_PASSWORD =", dbPass);
const mailgun = await env.get("MAILGUN_KEY", { appID : APP_ID, appCWD : __dirname });
console.log("MAILGUN_KEY =", mailgun);
}
catch (error)
{
console.error("[Client] read failed ~", error.code, error.message);
process.exitCode = 1;
}
})();
🧪 Example Workflows
🧭 Initialize Vault and Bootstrap Admin
const { createAegis } = require("@trap_stevo/aegis");
(async () => {
const vault = createAegis({ storagePath : "PROJECT", namespace : "vault" });
await vault.init();
await vault.bootstrapAdmin("admin:local", "BOOTSTRAP_TOKEN", "supersecure");
console.log("Vault initialized.");
})();
👤 Add Developer and Set Secrets
const vault = createAegis({ storagePath : "PROJECT" });
await vault.addDeveloper("devA", "temp123", "admin:local", "supersecure");
await vault.setSecret("SERVICE_API_KEY", "sk_live_123", "admin:local", "supersecure");
🧰 Using a Token Grant (CI/CD Mode)
await vault.addGrant("pipeline", {
type : "token",
path : "./deploy.sig",
adminPubKey : "BASE64_PUB_KEY",
alg : "ed25519"
}, "admin:local", "supersecure");
Then in the pipeline runner:
const { createAegisEnv } = require("@trap_stevo/aegis");
const env = createAegisEnv({ storagePath : "PROJECT" });
const key = await env.get("SERVICE_API_KEY", { appID : "pipeline", appCWD : process.cwd() });
console.log(key);
####🔌 Plugin Grant Example
await vault.addGrant("custom-app", {
type : "plugin",
modulePath : "./verifyCustom.js",
moduleHash : "sha256_of_module",
config : { allow : ["CI", "PROD"] }
}, "admin:local", "supersecure");
verifyCustom.js must export:
exports.verifySync = ({ meta, appCWD, config }) => {
return config.allow.includes("PROD");
};
🧰 Development Mode (No Grant Enforcement)
Set environment variable:
AEGIS_GRANTS_MODE=permissive
This bypasses strict grant verification for local testing.
⚡ Troubleshooting
- ERR_NO_GRANT – Missing grant for appID
- ERR_UNAUTHORIZED – Invalid signature, token, or module hash
- ERR_UNVERIFIED_MACHINE – Lockprint mismatch; regenerate lockprint or re-init vault
- Grant mismatch after editing file – Re-run
npm run start-aegis-set -- --grant
📜 License
See LICENSE.md
🛡️ Protect What Powers You
Aegis defends your application’s core credentials with simplicity and precision —
no agents, no cloud dependencies, no clutter. Just encrypted, attestable trust at rest and in runtime.