Infrastructure
Zero secrets in config.
Zero secrets in logs.
Every platform, every orchestrator, every CI runner. The proxy works with anything that makes HTTP calls. The CLI works with anything that can shell out. If your system is older than your career, it still works.
The proxy is the universal integration.
If your workload makes HTTPS calls, the Clavitor proxy injects credentials at the network layer. No code changes. No SDKs. No secrets in environment variables, config files, or logs. Set HTTPS_PROXY and your existing code works unchanged — the proxy resolves clavitor:// references in request headers before the request leaves the machine.
$ export HTTPS_PROXY=http://localhost:1983 $ curl -H "Authorization: Bearer clavitor://Stripe API/key" \ https://api.stripe.com/v1/charges # The agent never sees sk_live_... — only clavitor:// appears in logs
Containers
Docker and Kubernetes
Docker Compose
Run the Clavitor proxy as a sidecar. Your application containers point at the proxy — credentials are injected transparently. No secrets in environment variables, no secrets baked into images.
# docker-compose.yml
services:
clavitor-proxy:
image: clavitor/proxy:latest
ports: ["1983:1983"]
app:
environment:
- HTTPS_PROXY=http://clavitor-proxy:1983
depends_on: [clavitor-proxy]$ clavitor-cli render app.config.template.yml | docker compose -f - up
$ 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 key)"
For runtime credential injection, deploy the proxy as a sidecar container in your pod. Application containers set HTTPS_PROXY to the sidecar. Credentials are resolved per-request, never stored in etcd.
IaC
Terraform, Ansible, Pulumi
Terraform
data "external" "clavitor" {
program = ["clavitor-cli", "get", "AWS Root", "--field", "secret_key"]
}
provider "aws" {
secret_key = data.external.clavitor.result.value
}- 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 }}"import { execSync } from 'child_process';
const dbPass = execSync('clavitor-cli get "Production DB" --field password').toString().trim();
new aws.rds.Instance("db", { masterPassword: new pulumi.secret(dbPass) });Pulumi
CI/CD
GitHub Actions, GitLab CI, Jenkins
GitHub Actions
- name: Deploy
run: |
clavitor-cli init ${{ secrets.CLAVITOR_TOKEN }}
kubectl create secret generic app-secrets \
--from-literal=api-key="$(clavitor-cli get 'Deploy Token' --field key)" \
--dry-run=client -o yaml | kubectl apply -f -deploy:
script:
- clavitor-cli init $CLAVITOR_TOKEN
- clavitor-cli get "Deploy Key" --field private_key | ssh-add -
- ssh deploy@production "systemctl restart app"pipeline {
stages {
stage('Deploy') {
steps {
sh 'clavitor-cli init $CLAVITOR_TOKEN'
sh 'clavitor-cli get "Deploy Key" --field private_key | ssh-add -'
sh 'ssh deploy@production "systemctl restart app"'
}
}
}
}Jenkins
SSH
Vault-stored keys
$ clavitor-cli get "Deploy Key" --field private_key | ssh-add - $ ssh deploy@production
The private key is piped directly into ssh-add. It never touches disk, never appears in shell history, and is cleared from the agent when the session ends.
Legacy systems
If it makes an HTTP call, it works.
The proxy doesn't care what language made the request. COBOL, FORTRAN, Perl, Visual Basic, a 30-year-old batch job — if the process makes an HTTPS request, the proxy intercepts it, resolves the clavitor:// reference, and injects the real credential. No code changes required.
For systems that can't make HTTP calls, use clavitor-cli render to resolve a config template before the process starts. The template is safe to store anywhere. The resolved output goes to stdin or a temporary file with restricted permissions.
# Resolve credentials before the batch job starts $ clavitor-cli render db-connect.template.cfg > /tmp/db-connect.cfg $ chmod 600 /tmp/db-connect.cfg $ /opt/legacy/batch-job --config /tmp/db-connect.cfg $ rm /tmp/db-connect.cfg
The pattern is always the same.
CLI for scripts and pipelines. Proxy for HTTP workloads. Render for config files. Every secret resolved at runtime, never stored.