doppler-secrets
Use the Doppler CLI to access and manage secrets safely in both ad hoc scripts and long-lived projects. Covers CLI install, env injection, project binding via doppler.yaml, environments, service tokens, Docker, Kubernetes, and CI/CD integration. Use when a task touches secrets and must avoid exposing them in logs, prompts, command history, or tool output.
- License 许可
- MIT
- 最近更新
- 2026-11-12
- Stars
- ★ 1
- Forks
- 0
01 前言 Front Matter
- name
- doppler-secrets
- description
- Use the Doppler CLI to access and manage secrets safely in both ad hoc scripts and long-lived projects. Covers CLI install, env injection, project binding via doppler.yaml, environments, service tokens, Docker, Kubernetes, and CI/CD integration. Use when a task touches secrets and must avoid exposing them in logs, prompts, command history, or tool output.
- compatibility
- Requires the Doppler CLI and a Doppler account (DOPPLER_TOKEN or doppler login).
02 资源文件 6
- 参考文档resources/core-module.yaml723 B
- 脚本scripts/bmad_init.py20.7 KB
- 脚本scripts/tests/test_bmad_init.py11.0 KB
- 其他templates/Dockerfile.doppler.snippet1.1 KB
- 参考文档templates/doppler.yaml620 B
- 脚本templates/secure_python_with_doppler_cli_env.py724 B
03 SKILL.md 正文
<objective> Provide a single, authoritative workflow for using the Doppler CLI to handle secrets safely across ad hoc scripting and long-lived projects. </objective>
<essential_rules>
- Doppler CLI only.
- Never use the Doppler MCP for secret access.
- Use the
dopplerCLI for all reads, writes, validation, and runtime injection.
- Never expose secret values.
- Never print secrets to stdout/stderr.
- Never include secret values in LLM/tool message bodies, prompts, or files.
- Never serialize secrets into files, stack traces, debug dumps, or shell history.
- When commands carry tokens, set
export HISTIGNORE='doppler*:export DOPPLER_TOKEN*'first.
- Prefer env injection over value retrieval.
- Primary pattern:
doppler run --project=<p> --config=<c> -- <command>. - Application reads injected env vars internally.
- Avoid
doppler secrets get/doppler secrets downloadunless strictly required, and never log the output.
- Bind repos with a committed
doppler.yaml.
- Project-root
doppler.yamlletsdoppler setup --no-interactivework for teammates and CI. - Per-user state lives in
~/.doppler/.doppler.yamland must NOT be hand-edited. </essential_rules>
<step_0_install_hedge> Always check the CLI is installed before any other step. If missing, install via the OS-appropriate method below, then re-check.
Detection:
if ! command -v doppler >/dev/null 2>&1; then
echo "doppler CLI missing — installing" >&2
# run an install branch from the table below
fi
doppler --version
OS-specific install (use the first matching branch):
-
macOS (Homebrew):
brew install dopplerhq/cli/doppler -
Linux — Debian/Ubuntu (apt, signed repo, persistent):
sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gnupg curl -sLf --retry 3 --tlsv1.2 --proto "=https" \ 'https://packages.doppler.com/public/cli/gpg.DE2A7741A397C129.key' \ | sudo gpg --dearmor -o /usr/share/keyrings/doppler-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/doppler-archive-keyring.gpg] https://packages.doppler.com/public/cli/deb/debian any-version main" \ | sudo tee /etc/apt/sources.list.d/doppler-cli.list sudo apt-get update && sudo apt-get install -y doppler -
Linux — RHEL/CentOS/Fedora (yum/dnf):
sudo rpm --import 'https://packages.doppler.com/public/cli/gpg.DE2A7741A397C129.key' curl -sLf --retry 3 --tlsv1.2 --proto "=https" \ 'https://packages.doppler.com/public/cli/config.rpm.txt' \ | sudo tee /etc/yum.repos.d/doppler-cli.repo sudo dnf install -y doppler || sudo yum install -y doppler -
Linux/macOS fallback or CI — official install script:
(curl -Ls --tlsv1.2 --proto "=https" --retry 3 https://cli.doppler.com/install.sh \ || wget -t 3 -qO- https://cli.doppler.com/install.sh) | sh -
Windows (PowerShell, winget):
winget install doppler -
Docker / containers (no package manager): bake into the image — see
templates/Dockerfile.doppler.snippet.
Authoritative sources (consult only if you suspect a stale flag):
After install, verify:
doppler --version
Do NOT proceed if the CLI is still missing — report the install failure and stop. </step_0_install_hedge>
<quick_start>
- Ensure CLI installed (see step 0).
doppler login(once per machine; opens browser).- In repo root:
doppler setupto pick project + config (or commit adoppler.yaml). - Run code via
doppler run -- <command>. - For non-interactive environments (CI, prod, containers): use a service token via
DOPPLER_TOKEN. </quick_start>
──────────────────────────────────────────────────────── PART A — AD HOC SCRIPTS ────────────────────────────────────────────────────────
<ad_hoc_workflow>
<step_1_preflight> Verify CLI + auth:
command -v doppler >/dev/null || { echo "doppler CLI missing" >&2; exit 1; }
doppler configure debug >/dev/null 2>&1 || { echo "doppler not authed/configured" >&2; exit 1; }
</step_1_preflight>
<step_2_validate_required_names> Validate secret names only — never values:
doppler secrets --project=<project> --config=<config> --only-names --json
Compare required names against this list. Do not retrieve values during validation. </step_2_validate_required_names>
<step_3_execute_with_env_injection> Preferred:
doppler run --project=<project> --config=<config> -- python /path/to/script.py
Multi-command:
doppler run --project=<p> --config=<c> --command="./configure && ./run; ./cleanup"
</step_3_execute_with_env_injection>
<step_4_safe_python_pattern>
See templates/secure_python_with_doppler_cli_env.py. Read env, never print secrets:
import os, sys
required = ["X_OAUTH2_ACCESS_TOKEN"]
missing = [k for k in required if not os.getenv(k)]
if missing:
print(f"Missing required secret env vars: {', '.join(missing)}", file=sys.stderr)
raise SystemExit(1)
token = os.environ["X_OAUTH2_ACCESS_TOKEN"] # use directly; never log
</step_4_safe_python_pattern>
<step_5_output_sanitization> Allowed: counts, ids, timestamps, non-sensitive identifiers, summarized findings. Forbidden: token strings, secret values, env dumps, full credentialed request dumps. </step_5_output_sanitization>
</ad_hoc_workflow>
──────────────────────────────────────────────────────── PART B — PROJECTS / LONG-LIVED APPLICATIONS ────────────────────────────────────────────────────────
<project_workflow>
<step_1_bind_repo_to_project> Run once per repo, in repo root:
doppler setup
This writes scope into ~/.doppler/.doppler.yaml (per-user, never hand-edit).
For team-wide reproducibility, also commit a doppler.yaml at the repo root (see templates/doppler.yaml):
setup:
- project: my-app
config: dev
Monorepo variant:
setup:
- path: backend/
project: my-app-api
config: dev
- path: frontend/
project: my-app-web
config: dev
Teammates and CI then run:
doppler setup --no-interactive
</step_1_bind_repo_to_project>
<step_2_environments_and_configs>
Doppler hierarchy: Workspace → Project → Environment (dev/stg/prd) → Config.
- Branch configs (e.g.
dev_personal) inherit from a root config (dev) and override per-developer. - Promote secrets between environments via the dashboard (review/approval) rather than copy-paste.
- For new projects, bootstrap structure declaratively with
doppler-template.yaml+doppler import. See https://docs.doppler.com/docs/project-templates. </step_2_environments_and_configs>
<step_3_application_runtime>
Always launch the app under doppler run:
doppler run -- npm start
doppler run -- python -m myapp
doppler run -- ./bin/server
Do not call doppler secrets download to materialize a .env for the app at runtime if doppler run is viable.
</step_3_application_runtime>
<step_4_service_tokens_for_non_interactive> Service tokens are read-only, scoped to a single project+config. Use them everywhere a human is not present (CI, prod, containers, VMs).
Create:
# interactive setup, then mint
doppler setup
doppler configs tokens create ci-deploy --plain
# or single-shot
doppler configs tokens create ci-deploy \
--project my-app --config prd --plain
Ephemeral token (auto-expires):
DOPPLER_TOKEN=$(doppler configs tokens create job-$(date +%s) \
--project my-app --config prd --max-age 5m --plain)
Revoke:
doppler configs tokens revoke -p my-app -c prd dp.st.prd.xxxx
Auth precedence (highest → lowest): --token flag → DOPPLER_TOKEN env → --project/--config flags → directory scope in ~/.doppler/.doppler.yaml.
</step_4_service_tokens_for_non_interactive>
<step_5_ci_cd> GitHub Actions example (token from repo secrets):
- uses: dopplerhq/cli-action@v3
- env:
DOPPLER_TOKEN: ${{ secrets.DOPPLER_TOKEN_PRD }}
run: doppler run -- ./deploy.sh
Rules:
- Store the service token in the CI provider's secret store; never echo it.
- Use one token per environment (prd/stg/dev).
- Set
HISTIGNORE='export DOPPLER_TOKEN*'in any shell that may be recorded. </step_5_ci_cd>
<step_6_docker> Pattern A — bake CLI into image, inject token at runtime (recommended):
# see templates/Dockerfile.doppler.snippet for the full snippet
RUN (curl -Ls --tlsv1.2 --proto "=https" --retry 3 https://cli.doppler.com/install.sh) | sh
ENTRYPOINT ["doppler", "run", "--"]
CMD ["node", "server.js"]
Run:
docker run -e DOPPLER_TOKEN="$DOPPLER_TOKEN" my-app:latest
Pattern B — host-side injection (no Doppler in image):
doppler run -- docker compose up
Never COPY .env into an image. Never bake DOPPLER_TOKEN into a layer.
</step_6_docker>
<step_7_kubernetes> Two supported approaches:
-
Doppler Kubernetes Operator (recommended) — syncs Doppler configs into native
Secretobjects; pods consume viaenvFrom. Install via Helm; see https://docs.doppler.com/docs/kubernetes-operator. The Operator handles rotation; nodopplerbinary in the image. -
doppler runinside containers usingDOPPLER_TOKENfrom a K8s Secret:
kubectl create secret generic doppler-token \
--from-literal=DOPPLER_TOKEN='dp.st.prd.xxxx'
spec:
containers:
- name: app
image: my-app:latest
envFrom:
- secretRef:
name: doppler-token
Prefer (1) for production. Use (2) when the Operator is not available. </step_7_kubernetes>
<step_8_local_env_hygiene>
- Do NOT commit
.env,.env.local,.env.*(except.env.examplecontaining names only). - DO commit
doppler.yaml(project binding) anddoppler-template.yaml(project bootstrap). - Add to
.gitignore:.env .env.* !.env.example - If a
.envmust be generated for a tool that cannot usedoppler run(e.g. some IDEs):
Treat the file as ephemeral, ensuredoppler secrets download --no-file --format env > .env.gitignorecovers it, and delete it after use. - Pre-commit hooks: enable a secret scanner (gitleaks, trufflehog) to catch accidental commits. </step_8_local_env_hygiene>
<step_9_rotation_and_history>
- View change history:
doppler secrets history SECRET_NAME(or dashboard). - Rotate via dashboard or integration (AWS/GCP/Azure rotation connectors).
- After rotation, restart consumers (apps re-read env at process start, not in-place).
- For automated rotation triggers, configure Doppler webhooks to ping your deploy/restart endpoint. </step_9_rotation_and_history>
</project_workflow>
──────────────────────────────────────────────────────── COMMON FAILURES & FIXES ────────────────────────────────────────────────────────
<common_failures_and_fixes>
doppler: command not found→ run install hedge for the OS (step 0) and re-verify withdoppler --version.- Auth/config not initialized →
doppler login(interactive) or setDOPPLER_TOKEN(non-interactive). - "This token does not have access to requested config" → token scope mismatch; mint a new token for the correct project+config.
- Wrong secrets returned → check resolution with
doppler configure debuganddoppler configure --scope $(pwd); confirmdoppler.yamlmatches the desired config. - Secrets logged accidentally → strip debug prints, redact exceptions, never dump env or auth headers.
- Missing secrets at runtime → verify names exist in selected project/config (
doppler secrets --only-names) and confirm the runtime is actually underdoppler runor hasDOPPLER_TOKENset. - Token leaked in shell history → rotate the token immediately (
doppler configs tokens revoke), mint a new one, and setHISTIGNOREgoing forward. </common_failures_and_fixes>
──────────────────────────────────────────────────────── VERIFICATION CHECKLIST ────────────────────────────────────────────────────────
<verification_checklist>
- [ ]
doppler --versionsucceeds (CLI installed) - [ ] Auth confirmed (
doppler configure debugshows token source) ORDOPPLER_TOKENset - [ ] For projects:
doppler.yamlcommitted;.env*ignored;.env.example(names only) optional - [ ] Secret names validated without reading values
- [ ] Application launched via
doppler run(or Operator-injected env) - [ ] No secret output in logs/messages/files/shell history
- [ ] Service tokens scoped per environment; no human tokens in CI/prod
- [ ] Final response sanitized </verification_checklist>
<success_criteria> Agents reliably install, configure, and operate Doppler — for one-off scripts and long-lived projects — using CLI env injection and scoped service tokens, while preserving strict non-disclosure of secret values across all outputs. </success_criteria>
04 同仓库更多 Skills
turnstile-spin
Set up Cloudflare Turnstile end-to-end in a project. Scan the codebase, create the widget via the Cloudflare API, embed it where user requests need bot verification (form submissions, SPA actions, API endpoints, download links, comment or vote submissions, etc.), wire canonical server-side siteverify in the customer's existing backend, validate, and persist the skill. Load this when a user asks to add Turnstile, set up CAPTCHA, protect a form or endpoint from bots, or fix a Turnstile integration. Uses Cloudflare's documented Turnstile contract.
frontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
source-insights
Prepare inspected source evidence, preserve exact citations, and publish reviewed insights into an explicit local library.
skill-graph
Discover skills and workflows through independent lexical search, relationship paths and a terminal graph.
session-search
Recall public session turns with exact provenance, bounded excerpts and independent piped exports.
newsletter
Produce a private local AI newsletter from bounded public research, with cited deep dives, HTML/Markdown output, Dagu scheduling and seven-day retention.