Sigillo replaces `.env` files with a **cloud-based secrets manager** you can self-host. Prefix your commands with `sigillo run` and secrets are injected as environment variables, never written to disk. ```bash # instead of this source .env && next dev # do this sigillo run -- next dev ``` ```diagram ┌────────────────┐ sigillo run -- next dev │ App Worker │ │ │ (sigillo.dev) │ │ 1. fetch secrets │ │ │──────────────────────────────────────▶│ decrypt │ │ { DB_URL, API_KEY, ... } │ AES-256-GCM │ │◀──────────────────────────────────────│ │ │ └────────────────┘ │ 2. spawn child with env vars │ ▼ ┌──────────────┐ │ next dev │ │ (child) │ └──────┬───────┘ │ │ 3. stdout / stderr ▼ ┌───────────────┐ │ redaction │ high-entropy values replaced with * │ filter │ secrets never reach your terminal └──────┬────────┘ │ ▼ terminal (safe output) ``` Secrets are **automatically redacted** from process output so they never leak into agent context windows, CI logs, or terminal history. **Open-source alternative** to [Doppler](https://doppler.com) and [Infisical](https://infisical.com). ## Why Sigillo? ### Why not Doppler or Infisical? - **Self-hosted**: runs on your own Cloudflare account. No centralized point of failure, no vendor lock-in. Your secrets never leave infrastructure you control. - **Free**: no per-seat pricing, no usage limits. Deploy it once, use it forever. - **Open source**: MIT licensed. Read the code, audit it, extend it. ### Why teams need this - **No more `.env` files**: secrets live in the cloud and are easy to share across machines. No more "can you send me the .env?" on Slack. - **Single source of truth**: stop duplicating secrets across platforms. In CI, you only need the Sigillo token. Use built-in scripts to sync secrets to Cloudflare, Vercel, Docker, and more. - **Collaborative secrets**: share secrets between team members through organizations with role-based access, instead of brittle `.env` files or pasting keys in DMs. - **Multi-environment management**: manage dev, staging, and production secrets in one place. Switch between environments with `-c production`. ### Why agents need this - **Don't let agents read your secrets**: agents should never see your raw secret values. Instead of giving agents access to `.env` files, use `sigillo run` to inject secrets into processes without exposing them. - **Automatic output redaction**: `sigillo run` replaces secret values in stdout/stderr with `*`, so secrets never enter your chat context window. Even if an agent runs `printenv`, it won't see the real values in the output. ## Install skill for AI agents ```bash npx -y skills add remorses/sigillo -g -y ``` This installs [skills](https://skills.sh) for AI coding agents like Claude Code, Cursor, Windsurf, and others. ## Install **curl** (downloads the native binary to `~/.sigillo/bin`): ```bash curl -fsSL https://sigillo.dev/install.sh | bash ``` **npm**: ```bash npm i -g sigillo ``` **Run without installing** via npx or bunx: ```bash npx sigillo run -- next dev bunx sigillo run -- next dev ``` ## Quick start **1. Add your secrets** at [sigillo.dev](https://sigillo.dev) (or your self-hosted instance). Create a project, add environments, and paste in your secrets from the web UI. **2. Login from the terminal** (opens a browser for device flow authentication): ```bash sigillo login ``` **3. Link your project** (picks the default project and environment for this directory): ```bash sigillo setup ``` This saves the project and environment for the current directory in `~/.sigillo/config.json` (not in the repo). Run it in the project root if you have a single project, or in each subfolder of a monorepo. Since the config is local to your machine, you need to run `sigillo setup` again after cloning the repo on a new machine. Alternatively, skip setup entirely and always pass `--project` and `--env` (or `-c`) flags. **4. Run your app** with secrets injected as environment variables: ```bash sigillo run -- next dev ``` That's it. No `.env` files, no copy-pasting keys. Go back to [sigillo.dev](https://sigillo.dev) any time to add, edit, or rotate secrets. The next `sigillo run` picks them up automatically. Migrating from Doppler? See the [Doppler migration guide](https://github.com/remorses/sigillo/blob/main/docs/doppler-migration.md). ## Setting up a new project The Quick Start above assumes you already have a project with secrets. This section walks through creating everything from scratch, either from the CLI or the [dashboard](https://sigillo.dev). Sigillo organizes secrets into a simple hierarchy: ```diagram Organization (my-company) │ ├── Project (api) │ ├── dev │ │ ├── DATABASE_URL = postgres://localhost/mydb │ │ ├── API_KEY = sk-dev-xxx │ │ └── AUTH_SECRET = random-dev-key │ ├── preview │ │ ├── DATABASE_URL = postgres://preview-host/mydb │ │ └── API_KEY = sk-preview-xxx │ └── prod │ ├── DATABASE_URL = postgres://prod-host/mydb │ └── API_KEY = sk-live-xxx │ └── Project (web) ├── dev │ └── NEXT_PUBLIC_API_URL = http://localhost:3001 └── prod └── NEXT_PUBLIC_API_URL = https://api.example.com ``` Each **organization** contains multiple **projects**. Each project has **environments** (dev, preview, prod by default). Secrets are scoped to a single environment. ### Create an organization Organizations group projects and team members together. You need one before creating any project. **CLI:** ```bash sigillo orgs create --name my-company ``` **Dashboard:** Go to [sigillo.dev](https://sigillo.dev) and click "Create Organization" from the sidebar. ### Create a project A project holds secrets for one app or service. Creating a project automatically gives you three environments: **dev**, **preview**, and **prod**. ```bash sigillo orgs # find your org ID sigillo projects create --org --name my-app ``` **Dashboard:** Open your org, click "New Project", and give it a name. The three default environments are created for you. ### Link a directory `sigillo setup` saves the **default project and environment** for the current directory. This is a local-only setting stored in `~/.sigillo/config.json`, not in the repository. After setup, every `sigillo run` in that directory (or any subdirectory) resolves the right secrets without extra flags. Run it in the **project root** for single-project repos, or in **each subfolder** of a monorepo: ```bash # single project cd my-app sigillo setup --project --env dev # monorepo cd monorepo/api && sigillo setup --project api_xxx --env dev cd monorepo/web && sigillo setup --project web_xxx --env dev ``` Since the config lives on your machine (not in the repo), you need to re-run `sigillo setup` after cloning on a new machine. If you prefer not to run setup at all, you can always pass `--project` and `--env` explicitly: ```bash sigillo run --project -c dev -- next dev ``` Without flags, `sigillo setup` shows an interactive picker. Use `--project` and `--env` for non-interactive/CI workflows. ### Add secrets Add the secrets your app needs. You can set real values now, or leave them empty and fill them in later from the dashboard. ```bash sigillo secrets set DATABASE_URL "postgres://localhost:5432/mydb" -c dev sigillo secrets set API_KEY "" -c dev sigillo secrets set AUTH_SECRET "" -c dev ``` Repeat for other environments: ```bash sigillo secrets set DATABASE_URL "" -c preview sigillo secrets set DATABASE_URL "" -c prod ``` For encryption keys or auth secrets, generate a real random value right away: ```bash sigillo secrets set AUTH_SECRET "$(openssl rand -base64 32)" -c dev sigillo secrets set AUTH_SECRET "$(openssl rand -base64 32)" -c preview sigillo secrets set AUTH_SECRET "$(openssl rand -base64 32)" -c prod ``` **Dashboard:** Open your project at `sigillo.dev/orgs//projects//envs/dev` to add or edit secrets from the web UI. You can toggle between environments using the tabs. ### Verify and run ```bash sigillo secrets -c dev # list secret names (values hidden) sigillo run -c dev -- pnpm dev ``` ## Features | Feature | Description | |---|---| | **Secret injection** | `sigillo run -- ` injects secrets as env vars, no files on disk | | **Output redaction** | High-entropy values automatically replaced with `*` in stdout/stderr | | **File mount** | `--mount .env` writes secrets to the given file path, deletes it after the process exits | | **Organizations** | Multi-tenant orgs with admin/member roles and invite links | | **Projects & environments** | Organize secrets into projects with dev/preview/production environments | | **Audit log** | Append-only event log tracks every secret change with user attribution | | **API tokens** | Scoped to project or single environment, SHA-256 hashed, shown once | | **Device flow** | RFC 8628 login for CLI and agents, no copy-pasting tokens | | **AES-256-GCM encryption** | Every secret encrypted at rest with a random 12-byte IV | | **Download formats** | Export as `json`, `env`, `yaml`, `docker`, `dotnet-json`, `xargs` | | **Web UI** | Full management dashboard with Doppler-style hidden values | | **Self-hostable** | Runs on Cloudflare Workers + D1, deploy your own instance | | **REST API** | OpenAPI-documented API for building custom integrations | ## CLI reference ### `sigillo login` Authenticate via device flow or bearer token. ```bash sigillo login # interactive device flow sigillo login --token sig_xxx # save existing API token sigillo login --api-url https://my-instance.dev --scope . # custom instance, scoped to current dir ``` ### `sigillo setup` Save the default project and environment for the current directory. This is stored locally in `~/.sigillo/config.json`, not in the repo, so it needs to be done on each machine after cloning. Run it in the project root, or in each subfolder of a monorepo. You can skip setup entirely by always passing `--project` and `--env` flags to other commands. ```bash sigillo setup # interactive project/env picker sigillo setup --project proj_abc --env dev # non-interactive ``` ### `sigillo run` Execute a command with secrets injected as environment variables. ```bash sigillo run -- next dev # inject secrets from the configured env sigillo run -c dev -- next dev # use the dev environment sigillo run -c preview -- next dev # use the preview environment sigillo run -c production -- next build # use the production environment sigillo run -- printenv # verify which vars are injected (values redacted) sigillo run --command 'echo $MY_SECRET' # shell string mode sigillo run --mount .env -- npm start # write to file, clean up after sigillo run --mount config.json --mount-format json -- next dev # mount as JSON sigillo run --disable-redaction -- ./my-script.sh # opt out of output redaction ``` Use **`--command`** when you need shell features like `&&`, pipes, redirects, or `$VARIABLE` expansion. Wrap the command in single quotes so your parent shell does not expand secret variables before Sigillo injects them. ```bash # Wrong: your shell expands $DATABASE_URL before sigillo starts sigillo run --command "psql $DATABASE_URL -c 'select 1'" # Right: $DATABASE_URL expands inside sigillo's child shell sigillo run --command 'psql $DATABASE_URL -c "select 1"' ``` Put **non-secret env vars before** `sigillo run`, especially in package scripts. This keeps regular build flags visible while secrets still come from Sigillo. ```json { "scripts": { "deployment": "CLOUDFLARE_ENV=preview sigillo run -c preview --command 'vite build && wrangler deploy --env preview'" } } ``` **Output redaction** is enabled by default. Secret values with high entropy (>=3.5 Shannon bits, >=16 chars) are replaced with `*` in stdout/stderr. This prevents secrets from leaking into agent context windows or CI logs. ### Local package binaries When you run `sigillo run` through a package manager script (`pnpm run`, `bun run`, `npm run`), the package manager adds `node_modules/.bin` to `PATH` before Sigillo starts. Sigillo inherits that `PATH` and passes it to the child process, so local binaries like `vite`, `tsc`, `wrangler` are all available without prefixing with `pnpm exec` or `npx`. ```bash # in package.json scripts, local bins just work: sigillo run -- vite build # vite found via node_modules/.bin sigillo run -- wrangler deploy # wrangler found via node_modules/.bin sigillo run -- tsc --noEmit # tsc found via node_modules/.bin # same with --command: sigillo run --command 'vite build && wrangler deploy' ``` This also works when running `sigillo run` directly with `pnpm exec` or `bunx`: ```bash pnpm exec sigillo run -- vite dev bunx sigillo run -- next build ``` If you installed Sigillo globally (via `curl` or `npm i -g`), running `sigillo run` outside a package manager script means `node_modules/.bin` is **not** in `PATH`. In that case, use the full path or prefix with `npx`/`pnpm exec` inside the child command, or run Sigillo from a package script instead. ### `sigillo secrets` Manage individual secrets. ```bash sigillo secrets # list secret names sigillo secrets get DATABASE_URL # get a single value sigillo secrets get DATABASE_URL --force # allow value output inside agent shells sigillo secrets set API_KEY sk-live-xxx # set a value echo "multiline\nvalue" | sigillo secrets set CERT # set from stdin sigillo secrets delete OLD_KEY # delete sigillo secrets download # download all (YAML) sigillo secrets download --format json # download as JSON sigillo secrets download --format env # download as .env ``` Inside AI agent shells, `secrets get` and `secrets download` refuse to print raw values to a terminal unless you pass `--force`. Prefer `sigillo run` or a direct pipe so secret values go straight to the tool that needs them, not into the chat context. ```bash sigillo run --command 'psql "$DATABASE_URL" -c "select 1"' sigillo secrets download --format env | fly secrets import --app my-app ``` ### `sigillo projects` ```bash sigillo projects # list all projects sigillo projects create --org org_abc --name my-app # create project sigillo projects get proj_abc # show project details sigillo projects update proj_abc --name new-name # rename sigillo projects delete proj_abc # delete ``` ### `sigillo environments` ```bash sigillo environments # list environments sigillo environments create --project proj_abc --name Staging --slug staging # create sigillo environments rename env_abc --name Production --slug prod # rename sigillo environments delete env_abc # delete ``` ### Global flags Most commands that resolve auth, project, or environment from config accept these overrides: | Flag | Env var | Description | |---|---|---| | `--token ` | `SIGILLO_TOKEN` | Bearer token for auth | | `--api-url ` | `SIGILLO_API_URL` | API endpoint (default: `https://sigillo.dev`) | | `--env ` / `--config ` / `-c ` | `SIGILLO_ENVIRONMENT` | Environment slug (e.g. `dev`, `prod`) | | `--project ` / `-p ` | `SIGILLO_PROJECT` | Project ID override | ### Download formats | Format | Flag | Use case | |---|---|---| | `json` | `--format json` | Application config files | | `env` | `--format env` | Shell scripts with quotes | | `env-no-quotes` | `--format env-no-quotes` | Shell scripts without quotes | | `yaml` | `--format yaml` | Default CLI output | | `docker` | `--format docker` | Docker `--env-file` | | `dotnet-json` | `--format dotnet-json` | .NET `appsettings.json` (uses `__` for nested keys) | | `xargs` | `--format xargs` | NUL-delimited pairs for shell pipelines | ## Integrations ### Cloudflare Workers Upload secrets to a Cloudflare Worker using `wrangler secret bulk`: ```bash sigillo secrets download -c production --format env | wrangler secret bulk --env="" ``` The pipe sends the complete Sigillo environment directly to Wrangler. Secret values never appear in the terminal and no `.env` file remains on disk. Use an explicit empty environment for the top-level production Worker; Wrangler warns when a configuration has named environments but the target is ambiguous. Add these as `package.json` scripts so you can sync before each deploy: ```json { "scripts": { "secrets:preview": "sigillo secrets download -c preview --format env | wrangler secret bulk --env preview", "secrets:production": "sigillo secrets download -c production --format env | wrangler secret bulk --env=\"\"" } } ``` This intentionally syncs the entire selected environment. Keep `dev`, `preview`, and `production` values separate in Sigillo, then use the matching Wrangler environment at deployment time. ### Vercel `vercel env add` only accepts one variable at a time. Use the `xargs` format to pipe them: ```bash sigillo secrets download -c production --format xargs | \ xargs -0 -n2 sh -c 'printf %s "$2" | vercel env add "$1" production --force' sh ``` Add `--sensitive` to mark values as sensitive in Vercel: ```bash sigillo secrets download -c production --format xargs | \ xargs -0 -n2 sh -c 'printf %s "$2" | vercel env add "$1" production --sensitive --force' sh ``` As a `package.json` script: ```json { "scripts": { "secrets:vercel": "sigillo secrets download -c production --format xargs | xargs -0 -n2 sh -c 'printf %s \"$2\" | vercel env add \"$1\" production --sensitive --force' sh" } } ``` ### Fly.io `fly secrets import` reads `NAME=VALUE` pairs from stdin. Pipe `sigillo secrets download` directly, no temp file needed: ```bash sigillo secrets download -c production --format env | fly secrets import --app my-app ``` By default `fly secrets import` triggers a machine restart once secrets are staged. Use `--stage` to skip the restart and deploy separately: ```bash # stage without restarting sigillo secrets download -c production --format env | fly secrets import --app my-app --stage # then deploy when ready fly deploy --app my-app ``` Add as `package.json` scripts: ```json { "scripts": { "secrets:fly:production": "sigillo secrets download -c production --format env | fly secrets import --app my-app", "secrets:fly:preview": "sigillo secrets download -c preview --format env | fly secrets import --app my-app-staging" } } ``` ### Docker Mount secrets as a Docker env file: ```bash sigillo secrets download --format docker > .env.docker docker run --env-file .env.docker my-image ``` Or inject at build time: ```bash sigillo run -- docker compose up ``` ### CI / GitHub Actions Use an API token for non-interactive environments: ```yaml - name: Run with secrets env: SIGILLO_TOKEN: ${{ secrets.SIGILLO_TOKEN }} SIGILLO_PROJECT: ${{ vars.SIGILLO_PROJECT }} SIGILLO_ENVIRONMENT: ${{ vars.SIGILLO_ENVIRONMENT }} run: | npx sigillo run -- next build ``` ### .NET Download secrets as a hierarchical JSON file (keys with `__` become nested objects): ```bash sigillo secrets download --format dotnet-json > appsettings.Secrets.json ``` `DB__HOST=localhost` becomes `{ "Db": { "Host": "localhost" } }`. ## Self-hosting Sigillo runs on **Cloudflare Workers + D1**. You only need to deploy the **App Worker**. The Provider Worker (authentication) is optional because your self-hosted instance can use the hosted provider at `auth.sigillo.dev` by default. ```diagram Your Cloudflare account Sigillo Cloud ┌──────────────────────┐ ┌──────────────────────┐ │ App Worker │ OAuth │ Provider Worker │ │ (your secrets) │────────────▶│ (auth.sigillo.dev) │ │ │ PKCE │ │ │ You deploy this │◀────────────│ Already running │ └──────────────────────┘ └──────────────────────┘ ``` This means you don't need Google OAuth credentials and the deployment is a single worker. ### One command deploy The fastest way to self-host — no git clone, no build step: ```bash npx sigillo self-host ``` It logs into Cloudflare (reusing your `wrangler login` when present, or an OAuth browser flow, or a pre-filled API token link that works over SSH), creates the Worker and D1 database, applies migrations, and prints your instance URL. **Re-run the same command anytime to update** — only new migrations are applied and your auth secret is never rotated. ```bash # non-interactive (CI/agents) CLOUDFLARE_API_TOKEN=xxx npx sigillo self-host --yes # custom worker name and domain npx sigillo self-host --name sigillo --domain secrets.acme.com ``` ### Deploy from source 1. Clone the repo and install dependencies: ```bash git clone https://github.com/remorses/sigillo.git cd sigillo && pnpm install ``` 2. Create `app/.dev.vars` with your secrets: ``` BETTER_AUTH_SECRET= ENCRYPTION_KEY= ``` 3. Run locally: ```bash pnpm --dir app dev ``` 4. Deploy: ```bash pnpm --dir app deployment # deploy preview worker pnpm --dir app deployment:prod # deploy production worker ``` The app auto-registers with `auth.sigillo.dev` on first request via [RFC 7591](https://tools.ietf.org/html/rfc7591) dynamic client registration. No Google OAuth credentials needed, no manual setup. ### Self-hosting the provider (optional) By default, your self-hosted app uses `auth.sigillo.dev` for authentication. If you want a fully air-gapped setup with no dependency on Sigillo cloud, you can deploy the Provider Worker yourself. 1. Create `provider/.dev.vars` (requires Google OAuth credentials): ``` BETTER_AUTH_SECRET= GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= ``` 2. Deploy the provider: ```bash pnpm --dir provider deployment # deploy preview pnpm --dir provider deployment:prod # deploy production ``` 3. Point the app at your self-hosted provider by changing `PROVIDER_URL` in `app/wrangler.jsonc`: ```jsonc { "vars": { "PROVIDER_URL": "https://your-provider.your-domain.com" } } ``` Then redeploy the app. It will auto-register with your provider on the next request. ## How it works
Architecture Sigillo is two Cloudflare Workers in a monorepo, each backed by a D1 (SQLite) database: ```diagram ┌─────────────────────────────────────────────────────────────────┐ │ Your Machine │ │ │ │ sigillo run -- next dev │ │ │ │ │ │ device flow login (RFC 8628) │ │ │ or bearer token │ │ ▼ │ │ ┌──────────┐ │ │ │ Sigillo │ │ │ │ CLI │ │ │ └────┬─────┘ │ │ │ │ └───────┼─────────────────────────────────────────────────────────┘ │ REST API ▼ ┌──────────────────────┐ ┌──────────────────────┐ │ App Worker │ │ Provider Worker │ │ (self-hosted) │────────▶│ (auth.sigillo.dev) │ │ │ OAuth │ │ │ • Secrets CRUD │ PKCE │ • Google login │ │ • AES-256-GCM │ │ • OAuth2 / OIDC │ │ • Audit log │◀────────│ • Dynamic client │ │ • API tokens │ token │ registration │ │ • Device flow │ │ │ │ ┌────────────┐ │ │ ┌────────────┐ │ │ │ D1 (app) │ │ │ │ D1 (auth) │ │ │ └────────────┘ │ │ └────────────┘ │ └──────────────────────┘ └──────────────────────┘ ``` **App**: the secret manager you self-host. Handles secrets encryption, organizations, projects, environments, and the web UI. **Provider**: centralized OAuth provider at `auth.sigillo.dev`. Self-hosted instances register automatically via [RFC 7591](https://tools.ietf.org/html/rfc7591) dynamic client registration as public PKCE clients (no client secret needed).
Auth flow ```diagram CLI/Agent App (self-hosted) Provider (auth.sigillo.dev) │ │ │ │ POST /api/auth/device/code │ │ │─────────────────────────────▶│ │ │ { user_code, device_code } │ │ │◀─────────────────────────────│ │ │ │ │ │ User opens /device │ │ │ and enters user_code │ │ │ ┌────────────────────┼────── redirect ───────────────▶│ │ │ │ │ │ │ │ Google sign-in ──▶│ Google │ │ │ ◀── callback ─────│ │ │ │ │ │ │ │◀── auth code (PKCE) ───────────│ │ └────────────────────┼────── approved ───────────────▶│ │ │ │ │ Poll /api/auth/device/token │ │ │─────────────────────────────▶│ │ │ { access_token } │ │ │◀─────────────────────────────│ │ ```
Local dev vs CI authentication Two auth paths depending on the environment: ```diagram Local development CI / GitHub Actions ───────────────── ─────────────────── sigillo login SIGILLO_TOKEN=sig_xxx │ │ ▼ │ Browser opens /device │ │ │ ▼ │ Enter user_code │ │ │ ▼ │ Google sign-in │ │ │ ▼ ▼ Session cookie saved Bearer token from env in ~/.sigillo/config.json var or GitHub secret │ │ ▼ ▼ sigillo run -- next dev sigillo run -- next build ``` **Local**: interactive device flow (RFC 8628). Run `sigillo login` once, then the session is reused. **CI**: set `SIGILLO_TOKEN` as a secret in your CI provider. No browser needed, no interactive prompts.
Secrets encryption Every secret value is **AES-256-GCM** encrypted before storage. Each write generates a random 12-byte IV. The encryption key is either: - `ENCRYPTION_KEY`: 32 random bytes, base64-encoded (`openssl rand -base64 32`) - Derived from `BETTER_AUTH_SECRET` via SHA-256 (default if `ENCRYPTION_KEY` is not set) ```diagram plaintext value ("sk-live-xxx") │ ▼ ┌─────────────┐ ┌──────────────┐ │ AES-256-GCM │◀────│ 12-byte │ │ encrypt │ │ random IV │ └──────┬──────┘ └──────────────┘ │ ▼ ┌────────────────────────────────┐ │ secretEvent (append-only row) │ │ │ │ action: "set" │ │ name: "API_KEY" │ │ value: : │ │ userId: usr_abc │ │ createdAt: 1719000000 │ └────────────────────────────────┘ ``` Secrets are stored as an **append-only event log**. Current values are derived by replaying events. This gives you a full audit trail of every change with user/token attribution.
REST API The app exposes a full REST API with OpenAPI documentation at `/api/v0/openapi.json`. ```bash # list secrets curl -H "Authorization: Bearer sig_xxx" \ https://sigillo.dev/api/v0/projects/{projectId}/environments/{environmentId}/secrets # set a secret curl -X POST -H "Authorization: Bearer sig_xxx" \ -H "Content-Type: application/json" \ -d '{"name": "API_KEY", "value": "sk-live-xxx"}' \ https://sigillo.dev/api/v0/projects/{projectId}/environments/{environmentId}/secrets # bulk download as JSON curl -H "Authorization: Bearer sig_xxx" \ https://sigillo.dev/api/v0/projects/{projectId}/environments/{environmentId}/secrets/download?format=json # bulk set curl -X PUT -H "Authorization: Bearer sig_xxx" \ -H "Content-Type: application/json" \ -d '{"secrets": {"KEY1": "val1", "KEY2": "val2"}}' \ https://sigillo.dev/api/v0/projects/{projectId}/environments/{environmentId}/secrets ```
## License MIT