Delinea Secret Server

Stop Shipping
API Keys
in Your Code

How to remove hard-coded credentials from your applications using Delinea Secret Server — and why runtime credential injection is the right way to build.

Bruce Johnson
Bruce Johnson
Senior SE Manager, Commercial — Delinea
What we'll cover

Agenda

Part 1

The Problem

  • What are hard-coded credentials
  • Where they hide in real code
  • The real attack surface
  • Why devs keep doing it
Part 2

The Architecture

  • 3-layer security model
  • Runtime credential injection
  • How Secret Server fits in
  • The full code walkthrough
Part 3

The Payoff

  • What you gain immediately
  • Rotation without redeploy
  • Audit trail by default
  • Live demo
Business Risk

The Cost of Doing Nothing

$4.81M
Average cost of a credential-based breach (IBM 2024)
US companies pay $10.22M on average
292
days

Longest detection & containment time of any attack vector — credential breaches

$100K
max PCI DSS fine / month

Escalates from $5K–$10K/mo to $100K/mo after 6 months non-compliant, plus $50–$90 per affected customer.

2–3x
insurance premiums

Without PAM/secrets controls, premiums run 2–3x higher or coverage is denied. 30% of orgs can't even qualify.

28.65M new hardcoded secrets leaked to GitHub in 2025 alone — up 34% year-over-year. AI coding tools leak at 2x the baseline rate.

Business Value

The ROI of Getting It Right

$2.22M
saved on average

By organizations using credential automation (IBM 2024)

40%
faster deployment

Removes manual credential provisioning bottleneck

70%
less ops overhead

Financial services case study — 10,000+ API keys automated

Business Outcomes
  • Zero-redeploy rotation — rotate in Secret Server, apps pick it up on next request. No code change needed.
  • Audit-ready compliance — every fetch is a timestamped, attributable log entry. Cut audit time in half.
  • Cyber insurance qualification — 42% of orgs now require PAM to get a policy. Vault-based secrets management satisfies underwriters.
  • Blast radius containment — compromised env var doesn't hand over the key. Attacker still needs Delinea auth AND vault access.
  • Developer velocity — no more waiting on security team to rotate credentials. Automated and frictionless.

The math is simple: the average credential breach costs $4.81M. Secrets management automation saves $2.22M and cuts detection time. The investment pays for itself the first time it prevents — or contains — an incident.

The Big Picture

Build & Deploy Flow

💻
Write Code
Build your app
locally
📦
Commit
Push to
GitHub
Platform Builds
Vercel / Cloudflare
builds your site
🔑
Env Variables
Injects config
at build time
🛡
Secret Server
Fetches secrets
at runtime
Repeat — secrets rotate without code changes or redeployment
✓ No secrets in code
✓ No secrets in env vars
✓ Rotate anytime
The Problem

The Insecure Way — Hard-Coded Credentials

❌ insecure — node.js example // Somewhere in your application code...
// Or in a config file. Or .env committed to git.

const apiKey = "sk-ant-api03-abc123...";

const response = await fetch("https://api.anthropic.com/v1/messages", {
  headers: {
    "x-api-key": apiKey, // ← key is IN the source
  }
});
Where this key now lives
  • Your source code file — readable by everyone with repo access
  • Git history — forever, even after you "delete" it
  • Your deployment artifact — bundled, minified, but still there
The attack surface

Disgruntled or departing employee

Left the company. Still has a local clone — and the key in it.

Compromised developer machine

One infected laptop = every credential in every repo that dev had access to.

Accidentally public repo

Bots scan faster than humans react. Private for 30 seconds = already crawled.

You can't rotate fast enough

Hard-coded = code change + PR + review + deploy. Damage is done before you merge.

Risk Analysis

What's Actually at Risk

Credential typeHow it's typically hard-codedBlast radius
API Keys In source files, .env committed to git, config objects Critical
DB Passwords Connection strings in app config, JDBC URLs, ORM config Critical
Service Account Creds CI/CD pipelines, Dockerfiles, deployment scripts Critical
SSH Private Keys Bundled in containers, added to repos "temporarily" High
OAuth Secrets Client secrets in frontend code, env vars in CI logs High
Cloud Provider Keys AWS access keys, Azure SPs, GCP service accounts Critical
The Secure Way

Runtime Credential Injection — How It Works

1
Browser / Client
Only knows your app's API endpoint. View Source → nothing sensitive.
No credentials
2
Serverless Worker / Backend
Holds references to secrets — not the secrets themselves. Key is fetched at runtime.
References only
3
Secret Server Vault
The one place the credential lives. Every fetch is authenticated and logged.
Single source of truth
Secret Server showing the claude-api-key-my-bio secret with API Key field masked
Code Deep Dive — Layer 2

The Worker: Authentication to Secret Server

Step 1 — Get a bearer token from Delinea Platform
functions/api/chat.js const tokenRes = await fetch(env.DELINEA_TOKEN_URL, {
  method: "POST",
  body: new URLSearchParams({
    grant_type: "client_credentials",
    client_id: env.DELINEA_CLIENT_ID,
    client_secret: env.DELINEA_CLIENT_SECRET,
    scope: "xpmheadless",
  })
});
Step 2 — Use that token to pull the secret
const secretUrl =
  `${env.DELINEA_SS_BASE_URL}/api/v1/secrets/`
  + env.DELINEA_SECRET_ID;

const secretRes = await fetch(secretUrl, {
  headers: {
    Authorization: `Bearer ${accessToken}`
  }
});
Cloudflare secrets panel — actual project
Cloudflare Pages Variables and Secrets panel showing all DELINEA_* env vars encrypted

All 5 DELINEA_* vars are type Secret — values encrypted at rest, never exposed in UI or logs.

Code Deep Dive — The Key Variable

Where the API Key Lives — and Doesn't

❌ The insecure version
// Key is baked into the source artifact
const apiKey = "sk-ant-api03-abc123xyz...";

await fetch("https://api.anthropic.com/...", {
  headers: { "x-api-key": apiKey }
  // ↑ literal string is in this file
});

Search this file for sk-ant → key found.  Git blame → committed by a person, on a date.  Rotate? Requires a new deploy.

✓ The secure version
// Key is fetched from vault at runtime
let apiKey;
try {
  apiKey = await getAnthropicKey(env);
} catch (err) { ... }

await fetch("https://api.anthropic.com/...", {
  headers: { "x-api-key": apiKey }
  // ↑ variable, populated at runtime
});
Proof by Inspection

Search the Entire Codebase for sk-ant — Zero Results

VS Code search for sk-ant showing No results — proof the key is not in source code

VS Code search for sk-ant across the entire codebase → No results. The key string does not exist in source.

Operational Detail

Caching, Rotation, and Zero-Redeploy

The caching logic
// Module-level cache — survives across requests
// within the same worker instance
let cachedApiKey = null;
let cacheExpiry = 0;
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 min

async function getAnthropicKey(env) {
  if (cachedApiKey && Date.now() < cacheExpiry) {
    return cachedApiKey; // skip vault call
  }
  // ... fetch from Delinea ...
  cachedApiKey = keyField.itemValue;
  cacheExpiry = Date.now() + CACHE_TTL_MS;
}
What rotation looks like with this pattern
  • 1
    Admin rotates the key in Secret Server — one action in the vault UI. No code touched.
  • 2
    Currently cached workers continue using the old key for up to 5 minutes (the TTL).
  • 3
    On the next Delinea fetch (TTL expiry or cold start), the Worker gets the new key automatically.
  • 4
    Zero pull requests. Zero deployments. Zero downtime. No developer needed in the loop.
Compare: hard-coded key rotation
  • Find every place the key is used across all repos
  • Open PRs in each repo, get reviews, merge
  • Trigger deploys — hope nothing breaks
Security Properties

What You Get: Audit, Least Privilege, Zero Trust

Secret Server audit log showing every API key fetch by the Cloudflare service account with timestamps

Real audit log — every Password displayed entry is the Worker fetching the API Key field from the vault.

Audit trail Every access logged
Least privilege Scoped access only
Blast radius Contained compromise
Summary

The three things to take away

1
Hard-coded credentials are a permanent liability

Once a key is in source code, it's in git history forever — on every machine that ever cloned it.

2
Runtime injection separates what the code does from what it knows

The app holds a reference, not a credential. The real secret lives only in Secret Server.

3
This is the architecture enterprises run in production — and it's not complicated

OAuth2 + Secret Server API + environment secrets. Three components — works for any app type.

BJ
Bruce Johnson
Senior SE Manager, Commercial — Delinea  ·  15+ years in identity security & PAM