169 lines
6.8 KiB
Cheetah
169 lines
6.8 KiB
Cheetah
{{define "developers"}}
|
|
<div class="hero container">
|
|
<p class="label accent mb-4">Developers</p>
|
|
<h1 class="mb-4">One CLI call. Every secret.</h1>
|
|
<p class="lead">No env vars. No config files. No secrets sprawl. Every secret your infrastructure needs, one CLI call away.</p>
|
|
</div>
|
|
|
|
<hr class="divider">
|
|
|
|
<!-- The pattern -->
|
|
<div class="section container">
|
|
<p class="label accent mb-3">The pattern</p>
|
|
<h2 class="mb-4">Store it once. Retrieve it anywhere.</h2>
|
|
<p class="mb-8">The CLI is initialized once per machine. After that, any process can fetch secrets at runtime. The key is stored encrypted in the vault, never in env vars or source code. If the key rotates, update it in the vault UI — your services pick it up automatically.</p>
|
|
<div class="code-block mb-4">
|
|
<div><span class="comment"># One-time setup</span></div>
|
|
<div><span class="prompt">$</span> clavitor-cli init <token></div>
|
|
<div class="mt-2"><span class="comment"># Retrieve any secret, any time</span></div>
|
|
<div><span class="prompt">$</span> clavitor-cli get "OpenRouter API" --field password</div>
|
|
<div class="comment">sk-or-v1-abc123...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="divider">
|
|
|
|
<!-- Languages -->
|
|
<div class="section container">
|
|
<p class="label accent mb-3">Languages</p>
|
|
<h2 class="mb-8">Works in every language. No SDK required.</h2>
|
|
|
|
<h3 class="mb-3">Bash</h3>
|
|
<div class="code-block mb-6"><pre>DB_PASSWORD=$(clavitor-cli get "Production DB" --field password)
|
|
API_KEY=$(clavitor-cli get "OpenRouter API" --field password)
|
|
SSH_KEY=$(clavitor-cli get "Deploy Key" --field private_key)</pre></div>
|
|
|
|
<h3 class="mb-3">Go</h3>
|
|
<div class="code-block mb-6"><pre>key, _ := exec.Command("clavitor-cli", "get", "OpenRouter API", "--field", "password").Output()
|
|
db, _ := sql.Open("postgres", fmt.Sprintf("host=db user=app password=%s", strings.TrimSpace(string(key))))</pre></div>
|
|
|
|
<h3 class="mb-3">Python</h3>
|
|
<div class="code-block mb-6"><pre>import subprocess
|
|
api_key = subprocess.check_output(
|
|
["clavitor-cli", "get", "Stripe API", "--field", "password"]
|
|
).decode().strip()
|
|
stripe.api_key = api_key</pre></div>
|
|
|
|
<h3 class="mb-3">Rust</h3>
|
|
<div class="code-block mb-6"><pre>let key = std::process::Command::new("clavitor-cli")
|
|
.args(["get", "AWS Credentials", "--field", "password"])
|
|
.output()?.stdout;
|
|
std::env::set_var("AWS_SECRET_ACCESS_KEY", String::from_utf8(key)?.trim());</pre></div>
|
|
|
|
<h3 class="mb-3">TypeScript / Node</h3>
|
|
<div class="code-block mb-6"><pre>import { execSync } from 'child_process';
|
|
const apiKey = execSync('clavitor-cli get "Anthropic API" --field password').toString().trim();
|
|
const client = new Anthropic({ apiKey });</pre></div>
|
|
</div>
|
|
|
|
<hr class="divider">
|
|
|
|
<!-- Infrastructure -->
|
|
<div class="section container">
|
|
<p class="label accent mb-3">Infrastructure</p>
|
|
<h2 class="mb-8">Zero secrets in config.</h2>
|
|
|
|
<h3 class="mb-3">Docker Compose</h3>
|
|
<div class="code-block mb-6"><pre>services:
|
|
app:
|
|
environment:
|
|
- DB_PASSWORD=$(clavitor-cli get "Production DB" --field password)</pre></div>
|
|
|
|
<h3 class="mb-3">Terraform</h3>
|
|
<div class="code-block mb-6"><pre>data "external" "vault" {
|
|
program = ["clavitor-cli", "get", "AWS Root", "--json"]
|
|
}
|
|
provider "aws" {
|
|
secret_key = data.external.vault.result.password
|
|
}</pre></div>
|
|
|
|
<h3 class="mb-3">Kubernetes</h3>
|
|
<div class="code-block mb-6"><pre>kubectl create secret generic app-secrets \
|
|
--from-literal=db-pass="$(clavitor-cli get 'Production DB' --field password)" \
|
|
--from-literal=api-key="$(clavitor-cli get 'Stripe API' --field password)"</pre></div>
|
|
|
|
<h3 class="mb-3">Ansible</h3>
|
|
<div class="code-block mb-6"><pre>- name: Get database password
|
|
command: clavitor-cli get "Production DB" --field password
|
|
register: db_pass
|
|
no_log: true
|
|
|
|
- name: Configure app
|
|
template:
|
|
src: app.conf.j2
|
|
vars:
|
|
db_password: "{{"{{"}} db_pass.stdout {{"}}"}}"</pre></div>
|
|
|
|
<h3 class="mb-3">GitHub Actions</h3>
|
|
<div class="code-block mb-6"><pre>- run: |
|
|
echo "API_KEY=$(clavitor-cli get 'Deploy Token' --field password)" >> $GITHUB_ENV</pre></div>
|
|
|
|
<h3 class="mb-3">SSH with vault-stored keys</h3>
|
|
<div class="code-block mb-6"><pre>eval $(clavitor-cli get "Deploy Key" --field private_key | ssh-add -)
|
|
ssh deploy@production</pre></div>
|
|
</div>
|
|
|
|
<hr class="divider">
|
|
|
|
<!-- AI Agents -->
|
|
<div class="section container">
|
|
<p class="label accent mb-3">AI agents</p>
|
|
<h2 class="mb-8">Every agent. Scoped access. Audit trail.</h2>
|
|
|
|
<h3 class="mb-3">Claude Code</h3>
|
|
<div class="code-block mb-4"><pre># Skill auto-installed on init
|
|
clavitor-cli init <token>
|
|
clavitor-cli skill > ~/.claude/skills/clavitor.md
|
|
|
|
# Claude Code can now:
|
|
# "get me the AWS credentials"
|
|
# "what's the GitHub deploy token?"
|
|
# "store this API key as 'Stripe Prod'"</pre></div>
|
|
<p class="mb-6 text-sm">Add to any project's <code>CLAUDE.md</code>: <em>"Use clavitor-cli to retrieve secrets. Never hardcode secrets. Never store them in .env files."</em></p>
|
|
|
|
<h3 class="mb-3">OpenClaw</h3>
|
|
<div class="code-block mb-6"><pre># Skill auto-installed on init
|
|
clavitor-cli init <token>
|
|
# OpenClaw agents can now access vault entries within their scope</pre></div>
|
|
|
|
<h3 class="mb-3">Codex (OpenAI)</h3>
|
|
<div class="code-block mb-6"><pre>export CODEX_ENV_API_KEY=$(clavitor-cli get "OpenAI API" --field password)
|
|
codex --env API_KEY</pre></div>
|
|
|
|
<h3 class="mb-3">Cursor / Windsurf / Aider</h3>
|
|
<p class="mb-3 text-sm">Any agent that runs shell commands. Add to project instructions:</p>
|
|
<div class="code-block mb-6"><pre># "Use clavitor-cli to retrieve secrets. Never ask the user for passwords."</pre></div>
|
|
|
|
<h3 class="mb-3">CrewAI / LangChain / AutoGen</h3>
|
|
<div class="code-block mb-6"><pre>import subprocess
|
|
|
|
def get_secret(name, field="password"):
|
|
return subprocess.check_output(
|
|
["clavitor-cli", "get", name, "--field", field]
|
|
).decode().strip()
|
|
|
|
# As an agent tool
|
|
tools = [Tool(
|
|
name="get_credential",
|
|
description="Retrieve a credential from the vault",
|
|
func=lambda q: subprocess.check_output(["clavitor-cli", "get", q]).decode()
|
|
)]</pre></div>
|
|
|
|
<h3 class="mb-3">n8n / Make / Zapier</h3>
|
|
<div class="code-block mb-6"><pre>curl -H "Authorization: Bearer $CVT_TOKEN" \
|
|
https://vault.example.com/api/entries/search?q=Stripe</pre></div>
|
|
</div>
|
|
|
|
<hr class="divider">
|
|
|
|
<!-- CTA -->
|
|
<div class="section container">
|
|
<h2 class="mb-4">The pattern is always the same.</h2>
|
|
<p class="lead mb-6">One CLI call, any context. The agent's scope determines what it can see. The tier determines what it can decrypt.</p>
|
|
<div class="btn-row">
|
|
<a href="/install" class="btn btn-ghost">Self-host free →</a>
|
|
<a href="/hosted" class="btn btn-primary">Get hosted →</a>
|
|
</div>
|
|
</div>
|
|
{{end}}
|