Secrets Management
Fluxbase provides a secure secrets management system for storing API keys, database credentials, and other sensitive values that your edge functions and background jobs need at runtime.
Overview
Section titled “Overview”Secrets are:
- Encrypted at rest using AES-256-GCM
- Scoped to global or namespace level
- Version controlled with rollback support
- Injected automatically into function runtime as environment variables
CLI Commands
Section titled “CLI Commands”List Secrets
Section titled “List Secrets”View all secrets (values are never displayed):
# List all secretsfluxbase secrets list
# Filter by scopefluxbase secrets list --scope globalfluxbase secrets list --scope namespace
# Filter by namespacefluxbase secrets list --namespace productionCreate or Update a Secret
Section titled “Create or Update a Secret”# Create a global secretfluxbase secrets set API_KEY "sk-your-api-key"
# Create a namespace-scoped secretfluxbase secrets set DATABASE_URL "postgres://..." --scope namespace --namespace production
# Add a descriptionfluxbase secrets set STRIPE_KEY "sk_live_..." --description "Stripe production API key"
# Set an expirationfluxbase secrets set TEMP_TOKEN "xyz" --expires 30dGet Secret Metadata
Section titled “Get Secret Metadata”# Get metadata (value is never returned)fluxbase secrets get API_KEY
# For namespaced secretsfluxbase secrets get DATABASE_URL --namespace productionDelete a Secret
Section titled “Delete a Secret”# Delete a secretfluxbase secrets delete API_KEY
# Delete a namespaced secretfluxbase secrets delete DATABASE_URL --namespace productionVersion History
Section titled “Version History”Secrets maintain version history for audit and rollback:
# View version historyfluxbase secrets history API_KEY
# Rollback to a previous versionfluxbase secrets rollback API_KEY 2Scope Levels
Section titled “Scope Levels”Secrets support two scope levels:
| Scope | Description | Use Case |
|---|---|---|
global | Available to all functions in all namespaces | Shared API keys, common credentials |
namespace | Available only to functions in a specific namespace | Environment-specific secrets (prod vs staging) |
Resolution Order
Section titled “Resolution Order”When a function requests a secret, Fluxbase resolves it in this order:
- Namespace-scoped secret (if function is in a namespace)
- Global secret (fallback)
This allows you to override global defaults with namespace-specific values.
Using Secrets in Edge Functions
Section titled “Using Secrets in Edge Functions”Secrets are injected as environment variables with the FLUXBASE_SECRET_ prefix:
export default async function handler(req: Request): Promise<Response> { // Access secrets via environment variables const apiKey = Deno.env.get("FLUXBASE_SECRET_SENDGRID_API_KEY");
if (!apiKey) { return new Response("Missing API key", { status: 500 }); }
const response = await fetch("https://api.sendgrid.com/v3/mail/send", { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ // email data }), });
return new Response("Email sent");}Using the Secrets Object (Recommended)
Section titled “Using the Secrets Object (Recommended)”For cleaner code, use the built-in secrets object:
export default async function handler(req: Request): Promise<Response> { // Use the secrets helper const stripeKey = secrets.get("STRIPE_SECRET_KEY");
// Or require the secret (throws if missing) const requiredKey = secrets.getRequired("STRIPE_SECRET_KEY");
// Your logic here}Using Secrets in Background Jobs
Section titled “Using Secrets in Background Jobs”Background jobs have the same access to secrets:
export default async function handler(payload: unknown): Promise<void> { const apiKey = Deno.env.get("FLUXBASE_SECRET_EXTERNAL_API_KEY"); const dbUrl = Deno.env.get("FLUXBASE_SECRET_ANALYTICS_DB");
// Sync data to external service await syncToExternalService(apiKey, payload);}Settings Secrets vs Legacy Secrets
Section titled “Settings Secrets vs Legacy Secrets”Fluxbase provides two secrets systems:
| Feature | fluxbase settings secrets | fluxbase secrets |
|---|---|---|
| Storage | app.settings table | functions.secrets table |
| Scopes | System, User | Global, Namespace |
| User-specific | Yes (with HKDF encryption) | No |
| Version history | No | Yes |
| Function access | secrets.get() | Deno.env.get("FLUXBASE_SECRET_*") |
| Best for | Application config, per-user keys | Function runtime secrets |
For new projects, consider which system fits your needs:
- Edge function secrets: Use
fluxbase secrets(this guide) - Application configuration: Use
fluxbase settings secrets - Per-user API keys: Use
fluxbase settings secrets --user
Security Best Practices
Section titled “Security Best Practices”1. Use Namespace Scoping
Section titled “1. Use Namespace Scoping”Separate production and development secrets:
# Developmentfluxbase secrets set STRIPE_KEY "sk_test_..." --scope namespace --namespace development
# Productionfluxbase secrets set STRIPE_KEY "sk_live_..." --scope namespace --namespace production2. Set Expiration for Temporary Secrets
Section titled “2. Set Expiration for Temporary Secrets”# Expires in 30 daysfluxbase secrets set TEMP_TOKEN "xyz" --expires 30d
# Expires in 1 yearfluxbase secrets set ANNUAL_KEY "abc" --expires 1y3. Use Descriptive Names
Section titled “3. Use Descriptive Names”# Goodfluxbase secrets set SENDGRID_API_KEY "..." --description "SendGrid transactional email API key"
# Avoidfluxbase secrets set KEY1 "..."4. Rotate Secrets Regularly
Section titled “4. Rotate Secrets Regularly”Use version history to track changes:
# Update the secret (creates new version)fluxbase secrets set API_KEY "new-value"
# View historyfluxbase secrets history API_KEY
# Rollback if neededfluxbase secrets rollback API_KEY 15. Audit Secret Access
Section titled “5. Audit Secret Access”Check which functions use which secrets:
# Review function logs for secret accessfluxbase logs list --category execution --search "FLUXBASE_SECRET"Environment Variables
Section titled “Environment Variables”You can also provide secrets via environment variables when running Fluxbase:
# These are available to all functionsexport FLUXBASE_SECRET_API_KEY="your-key"export FLUXBASE_SECRET_DATABASE_URL="postgres://..."Environment variables take precedence over stored secrets, useful for:
- Local development
- CI/CD pipelines
- Kubernetes secrets injection
API Reference
Section titled “API Reference”REST Endpoints (Name-Based - Recommended)
Section titled “REST Endpoints (Name-Based - Recommended)”Name-based endpoints are the recommended way to work with secrets. They use the secret name instead of UUIDs, making them easier to use.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/secrets/by-name/:name | Get secret by name (query: namespace) |
| PUT | /api/v1/secrets/by-name/:name | Update secret by name (query: namespace) |
| DELETE | /api/v1/secrets/by-name/:name | Delete secret by name (query: namespace) |
| GET | /api/v1/secrets/by-name/:name/versions | Get version history by name (query: namespace) |
| POST | /api/v1/secrets/by-name/:name/rollback/:version | Rollback by name (query: namespace) |
REST Endpoints (UUID-Based - Legacy)
Section titled “REST Endpoints (UUID-Based - Legacy)”UUID-based endpoints are kept for backward compatibility. For new code, prefer name-based endpoints above.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/secrets | List all secrets (query: scope, namespace) |
| GET | /api/v1/secrets/stats | Get secret statistics |
| POST | /api/v1/secrets | Create a secret |
| GET | /api/v1/secrets/:id | Get secret metadata by UUID |
| PUT | /api/v1/secrets/:id | Update a secret by UUID |
| DELETE | /api/v1/secrets/:id | Delete a secret by UUID |
| GET | /api/v1/secrets/:id/versions | Get version history by UUID |
| POST | /api/v1/secrets/:id/rollback/:version | Rollback to version by UUID |
Request Body (Create)
Section titled “Request Body (Create)”{ "name": "API_KEY", "value": "sk-your-secret-key", "scope": "global", "namespace": "production", "description": "External API key", "expires_at": "2025-12-31T00:00:00Z"}Note: namespace is only required when scope is "namespace". The :id in UUID-based endpoints is a UUID returned after creation.
Request Body (Update)
Section titled “Request Body (Update)”{ "value": "new-secret-value", "description": "Updated description", "expires_at": "2026-12-31T00:00:00Z"}SDK Usage
Section titled “SDK Usage”The TypeScript SDK provides a secrets manager with both name-based and UUID-based methods:
import { createClient } from "@nimbleflux/fluxbase-sdk";
const client = createClient({ url: "http://localhost:8080" });
// Create a secretconst secret = await client.secrets.create({ name: "API_KEY", value: "sk-your-api-key", scope: "global", description: "External API key",});
// Get secret by name (recommended)const secret = await client.secrets.get("API_KEY");
// Get namespace-scoped secretconst secret = await client.secrets.get("DATABASE_URL", { namespace: "production",});
// Update secret by nameawait client.secrets.update("API_KEY", { value: "new-api-key" });
// Delete secret by nameawait client.secrets.delete("OLD_KEY");
// Get version historyconst versions = await client.secrets.getVersions("API_KEY");
// Rollback to version 2await client.secrets.rollback("API_KEY", 2);
// List all secretsconst secrets = await client.secrets.list();
// List by scopeconst globalSecrets = await client.secrets.list({ scope: "global" });
// Get statisticsconst stats = await client.secrets.stats();Next Steps
Section titled “Next Steps”- Edge Functions Guide - Deploy serverless functions
- Background Jobs Guide - Run scheduled and async jobs
- Configuration Reference - All config options