Security

How Nife.io Manages Secrets Without Trusting the Network

A deep dive into Nife’s Customer Vault: AES-CBC encryption, multi-provider support, audit logs, auto-rotation, and real-world usage.

Varun S
Varun S
15 min read
How Nife.io Manages Secrets Without Trusting the Network

How Nife.io Manages Secrets Without Trusting the Network

Every production application has secrets — database passwords, API keys, third-party tokens, signing certificates. The question isn't whether you have them. It's whether your platform handles them in a way that doesn't make a breach catastrophic.

Nife's Customer Vault is built around one hard rule: the server never sees plaintext. This post walks through how that works, what the vault actually does, real-world use cases for each feature, step-by-step usage, and why the architecture choices matter for teams running workloads across hybrid and multi-cloud environments.


The Problem with Naive Secret Storage

Most teams start with environment variables hardcoded in CI pipelines or .env files committed to private repos. This works until it doesn't — a misconfigured repo visibility, a CI log that echoes env vars, a colleague whose laptop is compromised.

Even platforms that store secrets server-side often transmit the plaintext value over HTTPS, trusting TLS as the only layer of protection. If the backend is ever read, the secrets are readable too.

Here is what real secret mismanagement looks like across teams:

MistakeConsequence
.env file pushed to a public repoFull credential leak, instant compromise
Hardcoded secrets in Docker image layersExtractable by anyone with image access
CI logs printing env varsSecrets visible in build history
Shared spreadsheet of passwordsNo audit trail, no rotation, no access control
One AWS IAM key used everywhereSingle point of failure across all environments

Nife takes a different approach — encrypt before sending, audit everything, and never let plaintext touch the wire.


AES-CBC Encryption Before the Request Leaves the Browser

The core security property of the Nife Vault is that secret values are encrypted in the browser using AES-CBC before any network request is made. The encryption key is derived from VITE_AES_KEY (or VITE_ENCRYPTION_KEY) — an environment variable baked into the frontend build, never sent to the backend.

This mirrors the Go backend's AesDeCrypt function — both sides use the same key, the same IV (the key itself, first 16 bytes), CBC mode, and PKCS7 padding. The only difference is direction: the frontend decrypts what the backend stores; the backend stores what the frontend encrypts.

What this means in practice:

  • The API endpoint receives a hex-encoded ciphertext blob, not a password
  • The database stores ciphertext
  • If the database is dumped, secrets are still protected by the AES key
  • Vault provider credentials (URL, token, mount path) go through the same encryption pipeline before leaving the browser

Multi-Provider Architecture

Not every team wants to run secrets inside Nife's infrastructure. Regulated industries often need secrets to stay inside their own AWS account or behind their own HashiCorp Vault. The Nife Vault is designed around this — it's a control plane, not just a store.

Supported providers:

ProviderIdentifierBest For
Nife Internal VaultINTERNALStartups, quick setup, no existing vault infra
HashiCorp VaultHASHICORP_VAULTEnterprises with self-hosted Vault already running
AWS Secrets ManagerAWS_SECRETS_MANAGERTeams already deep in the AWS ecosystem
Azure Key VaultAZURE_KEY_VAULTMicrosoft-centric orgs and Azure workloads
GCP Secret ManagerGCP_SECRET_MANAGERGCP-native teams and GKE deployments

Each provider is registered with a providerConfig blob — a JSON object containing credentials and connection details — which is itself encrypted before being sent to the backend. For HashiCorp Vault, this looks like:

{
  "url":         "https://vault.company.com:8200",
  "token":       "hvs.xxxxxxxxxxxxxxxx",
  "mount_path":  "secret",
  "auth_method": "token",
  "tls_verify":  true
}

This JSON is AES-encrypted using encryptForBackend() before the createVaultProvider GraphQL mutation fires.

How to Connect a Vault Provider

  1. Go to Governance → Secrets & Vault in your Nife dashboard
  2. Click Add Provider (top-right)
  3. Enter a Display Name like Prod AWS or Staging HashiCorp
  4. Select your Organization
  5. Pick a Provider Type from the dropdown
  6. Fill in the credentials for that provider (e.g. Vault URL + token for HashiCorp)
  7. Optionally check Set as default vault provider
  8. Click Add Provider

Tip: Use the Test Connection button on the provider card immediately after adding — it pings the provider and updates the health badge from unknown to healthy or unhealthy in real time.

Use Case — Keeping Secrets Inside Your Own AWS Account

A fintech company must not store customer-related credentials outside their AWS boundary due to compliance requirements. They:

  1. Connect their AWS Secrets Manager as a provider in Nife
  2. All secrets created in that org are routed to AWS — Nife stores only ciphertext references
  3. Rotation happens via AWS Secrets Manager's native engine
  4. Nife's audit log captures who accessed what and when, satisfying SOC 2 requirements

Provider Health and Sync

Each provider card reflects live health state polled after every test-connection and sync job. Health states are:

  • healthy — provider is reachable and responding correctly
  • unhealthy — provider is unreachable or returning errors
  • unknown — not yet checked Sync initiates a full reconciliation job. The UI polls the job every 3 seconds using the job ID returned by the sync endpoint, updating state until a terminal status is reached (completed, completed_with_errors, failed). A safety timeout clears the polling after 15 minutes regardless.

Use Case — Syncing an Existing HashiCorp Vault

A team already has 200+ secrets living in a self-hosted HashiCorp Vault. They want to manage them from Nife without re-entering them manually. They:

  1. Connect HashiCorp Vault as a provider
  2. Click Pull — all existing secrets are imported into Nife's index
  3. From now on, Sync keeps Nife's view aligned whenever secrets change in Vault
  4. The team manages secrets from Nife's UI; changes propagate back to HashiCorp on the next sync

Secret Lifecycle

Creating a Secret

When a user clicks Add Secret, they select:

  1. Which vault to store it in (Internal or an external provider by its UUID)
  2. Which organization owns it
  3. A path (defaults to secrets)
  4. A key in UPPER_SNAKE_CASE, e.g. DATABASE_URL
  5. The plaintext value The value is encrypted client-side before the REST call to POST /api/v1/vault/secrets. The key undergoes format validation — only alphanumeric characters and underscores — before the request is sent.

How to Add Your First Secret

1. Click the Secrets tab
2. Click Add Secret
3. Store in → Internal Vault (or your connected provider)
4. Organization → select your org
5. Path → leave blank (defaults to "secrets")
6. Key → DATABASE_URL
7. Value → postgres://user:password@host:5432/mydb
8. Click Add Secret

The secret is now stored as ciphertext. The list shows •••••••• until you explicitly toggle visibility.

Use Case — Database Credentials for a Node.js API

A backend team deploys a Node.js API to Nife. Instead of putting DATABASE_URL in a .env file inside the container, they:

  1. Add DATABASE_URL as a secret in the vault
  2. Reference it by name in their Nife app configuration
  3. At deploy time, Nife injects the decrypted value as an environment variable
  4. The secret never appears in their Git history, Dockerfile, or CI logs

Use Case — On-Call Debugging

A production incident is happening. The on-call engineer needs to check whether the right database host is configured. Instead of SSHing into a container or asking a colleague, they:

  1. Open Secrets & Vault → Secrets tab
  2. Search for DATABASE_URL
  3. Click View → toggle the show/hide eye icon
  4. Confirm the host value, close the dialog
  5. The access is logged in Access Logs with their user ID and timestamp

Exporting Secrets as a .env File

Export .env fetches each secret individually via the detail endpoint to get the real value, then assembles a .env file:

DATABASE_URL="postgres://user:pass@host:5432/db"
STRIPE_KEY=sk_live_xxxxxxxx
REDIS_URL=redis://localhost:6379
DEBUG=false

Values with spaces, quotes, or shell-special characters are automatically wrapped in double quotes with proper escaping. The file is constructed in memory as a Blob download — no server round-trip for the assembled file.

Use Case — Local Development Setup for New Engineers

A new engineer joins the team. Instead of Slacking around credentials:

  1. A team lead opens Secrets & Vault → Secrets tab
  2. Clicks Export .env
  3. Sends the downloaded secrets.env file via an encrypted channel (or lets the new engineer download it themselves with read-only access)
  4. The engineer renames it .env and runs the app locally No credentials were shared in plaintext over Slack or email. The export is logged.

Bulk Import from .env

Import .env accepts a .env file and parses each KEY=VALUE pair into individual secret creation requests. This is the fastest way to migrate an existing application's secrets into the vault.

How to Bulk Import

1. Click the Secrets tab
2. Click Import .env
3. Paste your .env contents or upload the file
4. Confirm — each KEY=VALUE becomes a separate secret

Use Case — Migrating a Legacy Application to Nife

A team is moving a Django app from a bare VM to Nife. The VM has a .env file with 40+ secrets. They:

  1. scp the .env from the VM to their local machine
  2. Open Secrets & Vault → Import .env
  3. Upload the file — all 40 secrets are stored in the vault in one shot
  4. Remove the .env file from the VM
  5. The app is deployed on Nife with secrets injected at runtime

Organization-Level Multi-Tenancy

A single vault provider can serve multiple organizations. The link lives in a junction table and the UI exposes full CRUD over it:

  • Link Org — adds a new organization to the provider's allowed list
  • Unlink — removes an organization (requires confirmation)
  • Guard: you cannot unlink the last remaining organization; delete the provider instead

Use Case — Platform Team Serving Multiple Product Teams

A platform engineering team manages one production HashiCorp Vault. Three product teams — payments, analytics, and notifications — each have their own Nife organization. The platform team:

  1. Creates the HashiCorp Vault provider once
  2. Links all three organizations to it via Link Org
  3. Each product team creates and manages their own secrets within their org scope
  4. The platform team retains visibility through the shared provider's audit log
  5. If the notifications team is disbanded, they Unlink that org — access revoked instantly

Secret Migration

The Migration tab solves a real operational problem: secrets accumulated in the internal vault (or an old provider) need to move to a new external provider without manual re-entry.

How to Migrate a Secret

1. Go to the Migration tab
2. Click Refresh to load migratable secrets
3. Find the secret — e.g. STRIPE_WEBHOOK_SECRET
4. Click Migrate
5. Select Target Vault Provider → e.g. "Prod AWS Secrets Manager"
6. Click Migrate Secret

The platform calls migrateSecret with preserveOriginal: false — the secret is written to the new provider and deleted from the source. One source of truth, always.

Use Case — Graduating from Internal Vault to AWS Secrets Manager

A startup begins with Nife's Internal Vault because it requires zero setup. After Series A, their compliance team requires all secrets to live in AWS Secrets Manager for SOC 2. They:

  1. Connect AWS Secrets Manager as a new provider
  2. Open the Migration tab
  3. Migrate each secret one by one (or automate via the API) to the new provider
  4. Internal Vault is now empty; all secrets live in AWS
  5. No secret value was ever re-typed manually

Audit Logs

Every vault operation — read, write, rotate, delete — produces an audit log entry. The Access Logs tab surfaces the last 100 entries:

FieldExample
Operationread / write / rotate / delete
Secret IDDATABASE_PASSWORD
Userjohn@acme.com or worker-service
ProviderProd HashiCorp
Client IP203.0.113.45
Statussuccess / failed
Timestamp2026-05-21 14:32:01

The log is append-only from the client's perspective — there is no delete UI for audit entries.

Use Case — Security Incident Investigation

A team notices unusual database activity at 2 AM. They open Access Logs and filter for DATABASE_PASSWORD. They see:

2026-05-21 02:14:33  read  DATABASE_PASSWORD  worker-cron  success
2026-05-21 02:14:41  read  DATABASE_PASSWORD  unknown-ip   success  ← suspicious

An IP they don't recognise accessed the secret. They immediately:

  1. Rotate DATABASE_PASSWORD via the Edit flow
  2. Check which deployments use that secret
  3. File an incident report — the audit log gives them the exact timestamp and IP

Use Case — SOC 2 / ISO 27001 Compliance Evidence

An auditor asks: "Can you prove that only authorised personnel accessed production credentials in Q1?" The team exports the Access Logs CSV for Q1, showing every read with user ID, timestamp, and IP. The audit passes.


Auto-Rotation and Settings

The Settings tab exposes three organization-wide controls, all saved via PATCH /api/v1/vault/settings with optimistic UI updates and automatic rollback on failure.

Auto-Rotation

Enable automatic secret rotation on a configurable schedule (1–365 days). The rotation engine on the backend handles the actual key refresh cycle — the UI just configures the policy.

How to Enable Auto-Rotation

1. Go to Settings tab
2. Toggle Enable Auto-Rotation → ON
3. Set rotation interval → e.g. 30 (days)
4. Save is automatic on toggle/blur

Use Case — PCI-DSS Compliance for Payment Secrets

PCI-DSS requires that cryptographic keys and credentials are rotated at least annually — many interpretations push for 90-day rotation. A payments team:

  1. Enables Auto-Rotation and sets interval to 90 days
  2. All secrets in scope rotate automatically
  3. No engineer needs to remember to do it manually
  4. The rotation event appears in Access Logs with operation rotate

Access Notifications

Toggle email alerts for secret access events. Useful for detecting unexpected reads.

Use Case — Detecting Anomalous Access

A team sets Access Notifications to security@company.com. At 3 AM on a Sunday, an automated alert fires — a service account read PAYMENT_GATEWAY_KEY from an IP in a region where the company has no infrastructure. The security team wakes up, investigates, and rotates the key before any damage is done.


Audit Log Retention

Configure how long audit log entries are retained (7–3650 days).

Compliance RegimeSuggested Retention
General / startup90–180 days
SOC 2365 days
GDPR365 days (with right-to-erasure carve-out)
PCI-DSS365 days minimum
HIPAA2190 days (6 years)
Financial services (some regions)2555 days (7 years)

Use Case — Contractor Access

A contractor is onboarded to help debug a production issue. They need to see which secrets are configured but must not be able to change or delete anything. The admin:

  1. Assigns the contractor view permission on the secrets module
  2. The contractor can open Secrets & Vault, see the list, and use View to inspect values
  3. Every Add Secret, Edit, Delete, Import, Sync, and Migrate button is disabled with a tooltip: "You don't have permission"
  4. The contractor's views are logged in Access Logs
  5. When the engagement ends, the admin removes the contractor's org membership — access is revoked immediately

Why This Matters for Hybrid Cloud

Teams running on Nife typically have workloads spread across multiple providers — a Kubernetes cluster on AWS, some edge nodes running BYOH, a few managed databases on GCP. Each environment needs the same database password, the same Stripe key, the same OAuth client secret.

The traditional answer is to duplicate secrets into each environment's secret store and keep them in sync manually. This creates drift, audit gaps, and multiple blast-radius points.

The Nife Vault solves this by being the single control plane: one place to create, rotate, audit, and revoke secrets, with provider routing determining where each secret actually lives at the storage layer. The sync and pull mechanisms keep external providers aligned without requiring manual reconciliation.


Quick Reference — Feature → Use Case Map

FeaturePrimary Use Case
Internal VaultStartups and new projects — zero config, immediate use
HashiCorp / AWS / Azure / GCP providerEnterprises with compliance requirements on secret residency
Bulk Import .envMigrating legacy apps to Nife without re-typing secrets
Export .envOnboarding new engineers with a one-time local dev setup
Provider SyncKeeping Nife aligned with an existing external vault
Provider PullOne-time import of all secrets from an existing vault
Multi-org linkingPlatform team sharing one vault across multiple product teams
Secret MigrationGraduating from Internal Vault to a compliance-required provider
Access LogsSecurity incident investigation and compliance evidence
Auto-RotationPCI-DSS, HIPAA, and SOC 2 rotation policy enforcement
Access NotificationsReal-time anomaly detection for unexpected secret reads
Audit Log RetentionConfiguring data retention to match your compliance regime
RBAC permissionsContractors, interns, and read-only roles with zero extra config

Related Resources

From the team at Nife

Deploy your next app in minutes, not days.

Nife is a multi-cloud edge platform that lets you deploy, scale, and manage applications globally without the infrastructure headache.