CLAVITORBlack-box credential issuance
Sign in Get free forever Get started

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.