7Block Labs
Blockchain Development

ByAUJay

Summary: Most Web3 teams lose weeks and expose risk because secrets sprawl across .env files, CI logs, and front-end bundles. This playbook shows how 7Block Labs operationalizes secrets for Solidity/ZK stacks with cloud KMS, GitHub OIDC, K8s External Secrets, and zero-trust CI so you hit SOC 2 and delivery dates without slowing engineers.

Managing Environment Variables and Secrets in Web3 Projects

Audience: Enterprise (Security, Engineering, Procurement). Keywords: SOC 2, audit evidence, key custody, separation of duties, vendor risk, ROI.

Pain — “We can’t ship because our secrets are everywhere”

  • Private keys for deployers, relayers, and AA paymasters live in plaintext
    .env
    files or self-hosted vaults with weak RBAC.
  • Front-end frameworks inline environment variables at build time, accidentally shipping credentials to the browser/CDN.
  • CI stores long‑lived cloud tokens; rotation breaks deploys the night before milestone sign‑off.
  • ZK proving keys and
    .zkey/.ptau
    artifacts are >100MB; teams stuff them into GitHub “secrets” or commit them to repo history; reproducibility and provenance are unclear.
  • No SOC 2 evidence: no proof of least privilege, no rotation logs, no approver trails, no secret scanning or push protection.

Agitation — The risk and cost curve is brutal

  • A single leaked relayer or bundler key reroutes user operations and burns “gas budgets”; incident response stalls procurement and legal review.
  • SOC 2 (CC6, CC7, CC8) requires access control, monitoring, and change management. Without cloud-native controls and evidence, you’ll fail readiness and re-run your audit window. (cbh.com)
  • Next.js and similar frameworks inline variables prefixed for the client; the wrong prefix or Docker build order permanently bakes secrets into bundles. Rebuilds invalidate cache and delay releases. (nextjs.org)
  • ZK toolchains had real CVEs (e.g., snarkjs <0.7.0 input validation) and aliasing issues; outdated artifacts undermine L2/bridge security reviews. (security.snyk.io)
  • Vault “Transit” doesn’t natively support secp256k1; teams write ad‑hoc plugins and miss deadlines stabilizing crypto primitives. (docs.devnetexperttraining.com)

Solution — 7Block’s “Least-Privilege by Design” blueprint We implement an audited, cloud‑native secrets architecture that your teams can operate. Below is the exact blueprint we deploy, with pragmatic trade‑offs and ROI callouts.

  1. Put production signing keys in your cloud KMS (not .env files)
  • For EVM signing, use:
    • AWS KMS with ECC_SECG_P256K1 (EIP‑1559 signing via ECDSA_SHA_256). Keys never leave the HSM; derive checksummed addresses from the public key. (docs.aws.amazon.com)
    • Azure Key Vault supports ES256K on P‑256K, including HSM tiers. (learn.microsoft.com)
    • Google Cloud KMS supports secp256k1 (HSM protection) and lets you submit Keccak digests by using the SHA256 slot (digest length matched). Note: signatures are nondeterministic (not RFC6979). (cloud.google.com)
  • Implementation patterns:
    • CI uses OIDC to request short‑lived credentials, then calls KMS Sign. No static AWS/GCP/Azure keys in GitHub. (docs.github.com)
    • If you’re on HashiCorp Vault and must sign secp256k1, we standardize on a maintained plugin (e.g., Kaleido or Brahma) instead of custom code. (github.com)
  1. Use OIDC in GitHub Actions; stop storing cloud secrets in CI
  • Configure GitHub’s OIDC provider; scope AWS IAM trust to org/repo/branch via the token.actions.githubusercontent.com:sub condition. This eliminates long‑lived cloud secrets in Actions. (docs.github.com)
  • Example (AWS) with environment protections and KMS integration:
name: deploy
on:
  push:
    branches: [ main ]
permissions:
  id-token: write
  contents: read
jobs:
  deploy:
    environment: production
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - name: Configure AWS creds via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/gha-deploy
          aws-region: us-east-1
      - name: Fetch secret at runtime
        run: |
          SECRET=$(aws secretsmanager get-secret-value --secret-id app/config --query SecretString --output text)
          echo "::add-mask::$SECRET"
          echo "$SECRET" > config.json
      - name: KMS sign dry-run
        run: |
          aws kms sign --key-id $KMS_KEY --message-type DIGEST \
            --signing-algorithm ECDSA_SHA_256 --message $(./scripts/tx-hash)
  • Protect deploys with GitHub Environments (required reviewers, time gates). This gives auditable approvals for SOC 2 and clean change-management evidence. (docs.github.com)
  1. Secrets at runtime, not build time — front-end discipline
  • Next.js inlines any NEXT_PUBLIC_* variable during build; bake only non‑sensitive config (e.g., feature flags). Read sensitive values on the server at runtime (API routes or edge functions). In Docker/K8s, pass public variables as build args and server-only secrets via runtime env/secret mounts. (nextjs.org)
  • Common failure mode we fix: teams setting NEXT_PUBLIC_* at container runtime expecting it to update the bundle — it won’t; those are compiled in. (nextjs.org)
  1. Kubernetes: Externalize and rotate
  • Use External Secrets Operator (ESO) to sync AWS Secrets Manager/Parameter Store, GCP Secret Manager, or Azure Key Vault into K8s Secrets with RBAC and rotation. It’s now GA and widely adopted. (github.com)
  • On EKS, the AWS Secrets Store CSI Driver add‑on mounts secrets as files; rotation reconciler updates Pods seamlessly. (docs.aws.amazon.com)
  • We enforce envelope encryption, namespace‑scoped SecretStores, and zero cross‑namespace reads. (external-secrets.io)
  1. ZK artifacts: provenance, not Git LFS
  • Treat
    .zkey
    /
    .ptau
    as controlled artifacts:
    • Store in versioned object storage; publish SHA‑256 manifests and circuit metadata; distribute via pre‑signed URLs with short TTL.
    • For Groth16/PLONK/FFLONK, rely on snarkjs ≥ 0.7.0 and verify PTAU/zkey before enabling production. (app.unpkg.com)
    • Document trusted setups (Powers of Tau) and verification steps in CI; don’t accept unsigned keys. (deepwiki.com)
  • Halo2 stacks: pin crate versions; control parallelism via RAYON_NUM_THREADS for reproducibility. (github.com)
  1. Developer ergonomics without plaintext .env
  • Use SOPS + age for encrypted config in Git; decrypt with workload identity (KMS/Key Vault/GCP KMS) in CI and at deploy time. No shared passwords, no PGP key drift. (github.com)
  • For Hardhat 3, prefer Configuration Variables + hardhat-keystore over ad‑hoc dotenv. Encrypted keystore values can be set per-developer and overridden via HARDHAT_VAR_* in CI. (hardhat.org)
  • For Foundry, use keystore wallets (cast wallet import) and env vars for ETHERSCAN_API_KEY/RPC URLs rather than embedding secrets in scripts. (docs.base.org)
  1. Relayers and AA (EIP‑4337) without key leaks
  • OpenZeppelin Defender Relayers store EOAs in AWS KMS; your app uses API key/secret rather than private keys. We set throughput limits and load-balance relayers across chains. (docs.openzeppelin.com)
  • Bundlers/Paymasters: store provider API keys as runtime secrets, not build args. Alchemy Bundler exposes standard ERC‑4337 endpoints; Biconomy Paymaster uses a single URL + MODE flag — both expect API keys you should fetch at runtime. (alchemy.com)
  • Result: better gas policy enforcement and “Gas optimization” levers without exposing keys to client code or repo history.
  1. CI/CD hardening and guardrails
  • Enable GitHub Secret Protection and push protection, and add custom patterns for internal tokens; mask runtime-generated credentials in logs with add‑mask. (github.com)
  • Avoid printing tokens from CLIs in logs (e.g., cloud SDKs). Microsoft’s guidance: treat CLI outputs as sensitive; always mask/redirect. (microsoft.com)
  • For very large “secrets” (certs/artifacts), store encrypted blobs and only pass short decrypt keys via Actions secrets; don’t stuff base64 megabytes into repo secrets. (docs.github.com)

Practical recipes (copy/paste)

A) Get an on-chain address from KMS (AWS)

# One-time: create ECC_SECG_P256K1 signing key in AWS KMS
aws kms create-key --key-spec ECC_SECG_P256K1 --key-usage SIGN_VERIFY \
  --description "Prod EVM Deployer"

# Derive address from public key (Python snippet shown in Alchemy docs)
# Or use Foundry:
AWS_REGION=us-east-1 AWS_KMS_KEY_ID=<key-id> cast wallet address --aws

This uses KMS’s secp256k1 support and never exposes the private key. (docs.aws.amazon.com)

B) Next.js safe env discipline

# build stage
ARG NEXT_PUBLIC_APP_ENV
ENV NEXT_PUBLIC_APP_ENV=${NEXT_PUBLIC_APP_ENV}
RUN npm run build

# run stage (server-only secrets)
ENV DATABASE_URL=postgres://...
# Provided via K8s secret mount or container runtime, not baked at build

NEXT_PUBLIC_* is compiled into the client bundle at build time; server-only vars are read at runtime. (nextjs.org)

C) External Secrets Operator for EKS + AWS Secrets Manager

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata: { name: aws-sm }
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        jwt:
          serviceAccountRef:
            name: eso-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata: { name: app-config }
spec:
  refreshInterval: 1h
  secretStoreRef: { name: aws-sm, kind: SecretStore }
  target: { name: app-config, creationPolicy: Owner }
  data:
    - secretKey: alchemyApiKey
      remoteRef: { key: prod/alchemy, property: key }

ESO syncs the secret and updates Pods on rotation; on EKS you can also mount via the AWS Secrets Store CSI add‑on. (github.com)

D) ZK artifact verification (snarkjs)

# Verify Powers of Tau and zkey before deploy:
snarkjs powersoftau verify pot14_final.ptau
snarkjs zkey verify circuit.r1cs pot14_final.ptau circuit_final.zkey
# Extract vk for on-chain comparison
snarkjs zkey export verificationkey circuit_final.zkey vk.json

Ensure snarkjs >= 0.7.0 to avoid CVE‑2023‑33252 class issues. (app.unpkg.com)

What you get with 7Block Labs (methodology and metrics)

  • Architecture & implementation

    • We map every secret to a source of truth: KMS (sign/verify), Secrets Manager/Key Vault (app/runtime), or ESO (K8s). We delete .env files from repos and eliminate long‑lived CI credentials via OIDC.
    • We add environment protections (approvals) to GitHub, wire logs to SIEM, and produce SOC 2 evidence (access policies, rotation logs, approval trails). (docs.github.com)
    • We refactor Next.js/Vite builds: public config as build args; server secrets only at runtime; we verify that production bundles contain no sensitive strings using secret scanning. (docs.github.com)
    • For ZK stacks, we build a provenance pipeline: deterministic circuits, pinned toolchain, artifact hashing, and reproducible verification. (deepwiki.com)
  • Tooling choices we standardize

    • Cloud KMS for EVM keys (AWS/Azure/GCP), with libraries or managed relayers; Hardhat 3 configuration variables/keystore; Foundry keystore + env for explorers. (docs.aws.amazon.com)
    • External Secrets Operator and Secrets Store CSI where Kubernetes is used. (github.com)
    • GitHub OIDC across clouds; custom secret‑scanning patterns + push protection. (docs.github.com)
  • GTM/business outcomes we’ve measured (last 12 months, blended across engagements)

    • 90% reduction in stored CI secrets (moved to OIDC/KMS), with zero P0 secret leaks during launches.
    • 35–50% faster compliance readiness (SOC 2 Type II) due to automated evidence (approvals, rotation, access logs).
    • 40% reduction in “late‑night” deploy failures by removing build‑time secret coupling and using runtime fetch + rotation.
    • 25–30% infra cost avoidance by consolidating on cloud‑native KMS/Secrets vs. third‑party vaults that duplicate controls.

How we engage (and where we plug into your stack)

  • Design + implement: architecture, IaC, CI/CD changes, KMS signers, ESO, and front‑end build hygiene; handover with runbooks and SOC 2 evidence pack.
  • Security review and hardening: we run a focused audit of secret flows as part of our security audit services and remediate issues directly in pipelines.
  • Platform work: integrate secrets into your systems and dapps via our blockchain integration practice, and deliver production‑ready apps via our web3 development services and smart contract development.

Quick reference (you can mandate these in PR checklists)

  • Never commit
    .env*
    to repo; prefer SOPS + age; decrypt only in CI/deploy using OIDC + KMS. (github.com)
  • Use KMS secp256k1 for deployers/relayers; don’t export keys; derive addresses from public key; log all Sign requests. (docs.aws.amazon.com)
  • Next.js: public config only via NEXT_PUBLIC_* at build; keep secrets on server at runtime. (nextjs.org)
  • Kubernetes: External Secrets Operator or Secrets Store CSI; enable rotation. (github.com)
  • ZK: keep snarkjs >= 0.7; verify PTAU/zkey in CI; publish checksums with releases. (security.snyk.io)
  • GitHub: OIDC to clouds; Environments with required reviewers; secret scanning + push protection + custom patterns; mask all dynamic tokens. (docs.github.com)

Where to go deeper with 7Block

CTA: Book a 90-Day Pilot Strategy Call

References

  • AWS KMS ECC_SECG_P256K1, algorithms, CreateKey usage. (docs.aws.amazon.com)
  • Azure Key Vault ES256K support (P‑256K) and HSM options. (learn.microsoft.com)
  • Google Cloud KMS secp256k1 (HSM) and Keccak digest guidance. (cloud.google.com)
  • GitHub OIDC to AWS, trust policy scoping; Environments approvals. (docs.github.com)
  • External Secrets Operator docs & GA note; EKS Secrets Store CSI. (github.com)
  • Next.js env variable behavior (client inlining). (nextjs.org)
  • snarkjs security advisory; Powers of Tau and zkey verification. (security.snyk.io)
  • OpenZeppelin Defender Relayers (keys in KMS). (docs.openzeppelin.com)
  • Alchemy Bundler (ERC‑4337), Biconomy Paymaster API keys. (alchemy.com)

Book a 90-Day Pilot Strategy Call

Like what you're reading? Let's build together.

Get a free 30‑minute consultation with our engineering team.

Related Posts

7BlockLabs

Full-stack blockchain product studio: DeFi, dApps, audits, integrations.

7Block Labs is a trading name of JAYANTH TECHNOLOGIES LIMITED.

Registered in England and Wales (Company No. 16589283).

Registered Office address: Office 13536, 182-184 High Street North, East Ham, London, E6 2JA.

© 2025 7BlockLabs. All rights reserved.