{
  "slug": "safe/ci-cd",
  "title": "Safe CI/CD",
  "description": "Resolve Safe references in CI/CD jobs without leaking values into scripts, logs, or process metadata.",
  "url": "https://cuitty.com/docs/safe/ci-cd",
  "markdown_url": "https://cuitty.com/docs/safe/ci-cd.md",
  "json_url": "https://cuitty.com/docs/safe/ci-cd.json",
  "frontmatter": {
    "title": "Safe CI/CD",
    "description": "Resolve Safe references in CI/CD jobs without leaking values into scripts, logs, or process metadata.",
    "order": 6,
    "section": "Safe",
    "updatedAt": "2026-06-09"
  },
  "headings": [
    {
      "depth": 1,
      "slug": "safe-cicd",
      "text": "Safe CI/CD"
    },
    {
      "depth": 2,
      "slug": "package-script-pattern",
      "text": "Package script pattern"
    },
    {
      "depth": 2,
      "slug": "job-flow",
      "text": "Job flow"
    },
    {
      "depth": 2,
      "slug": "service-accounts",
      "text": "Service accounts"
    },
    {
      "depth": 2,
      "slug": "cuitty-code-and-registry",
      "text": "Cuitty Code and Registry"
    }
  ],
  "body_markdown": "# Safe CI/CD\n\nCI/CD should use explicit Safe references only. Resolve values at the job boundary, inject them into the child process, and install redaction rules before the process starts.\n\n## Package script pattern\n\n```jsonc\n{\n  \"scripts\": {\n    \"deploy\": \"cuitty-safe run --scope acme/prod -- bun run deploy:raw\",\n    \"registry:publish\": \"cuitty-safe run --scope acme/registry -- bun publish\"\n  },\n  \"cuittySafe\": {\n    \"env\": {\n      \"DATABASE_URL\": \"acme/prod/database-url\",\n      \"REGISTRY_TOKEN\": \"acme/registry/publish-token\"\n    }\n  }\n}\n```\n\n## Job flow\n\n1. Load job configuration.\n2. Build the Safe reference set.\n3. Request a Safe run plan.\n4. Resolve values from the configured provider.\n5. Inject resolved env only into the child process.\n6. Install redaction rules for logs.\n7. Emit audit metadata without values.\n\n## Service accounts\n\nFor 1Password-backed production CI, use a least-privilege service account scoped to the required vault and fields. Cuitty Safe should read the token from the CI provider's secret store, commonly exposed as `OP_SERVICE_ACCOUNT_TOKEN`.\n\n```bash\ncuitty-safe connector 1password test --scope acme/prod\ncuitty-safe run --scope acme/prod -- bun run deploy:raw\n```\n\n## Cuitty Code and Registry\n\nCuitty Code can resolve app manifest env, runner env, mirror credentials, webhook signing secrets, OAuth app credentials, deployment keys, Airflow tokens, and Dagger tokens.\n\nCuitty Registry can resolve npm publish tokens, Cargo registry tokens, PyPI upload tokens, OCI credentials, artifact storage DSNs, signing keys, and provenance keys.\n\nDo not resolve Safe refs inside tight package download paths unless explicitly configured.",
  "body_html": "<h1 id=\"safe-cicd\">Safe CI/CD</h1>\n<p>CI/CD should use explicit Safe references only. Resolve values at the job boundary, inject them into the child process, and install redaction rules before the process starts.</p>\n<h2 id=\"package-script-pattern\">Package script pattern</h2>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"jsonc\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"scripts\"</span><span style=\"color:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"deploy\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"cuitty-safe run --scope acme/prod -- bun run deploy:raw\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"registry:publish\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"cuitty-safe run --scope acme/registry -- bun publish\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"cuittySafe\"</span><span style=\"color:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"env\"</span><span style=\"color:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"DATABASE_URL\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"acme/prod/database-url\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"REGISTRY_TOKEN\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"acme/registry/publish-token\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<h2 id=\"job-flow\">Job flow</h2>\n<ol>\n<li>Load job configuration.</li>\n<li>Build the Safe reference set.</li>\n<li>Request a Safe run plan.</li>\n<li>Resolve values from the configured provider.</li>\n<li>Inject resolved env only into the child process.</li>\n<li>Install redaction rules for logs.</li>\n<li>Emit audit metadata without values.</li>\n</ol>\n<h2 id=\"service-accounts\">Service accounts</h2>\n<p>For 1Password-backed production CI, use a least-privilege service account scoped to the required vault and fields. Cuitty Safe should read the token from the CI provider’s secret store, commonly exposed as <code>OP_SERVICE_ACCOUNT_TOKEN</code>.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">cuitty-safe</span><span style=\"color:#9ECBFF\"> connector</span><span style=\"color:#9ECBFF\"> 1password</span><span style=\"color:#9ECBFF\"> test</span><span style=\"color:#79B8FF\"> --scope</span><span style=\"color:#9ECBFF\"> acme/prod</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">cuitty-safe</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#79B8FF\"> --scope</span><span style=\"color:#9ECBFF\"> acme/prod</span><span style=\"color:#79B8FF\"> --</span><span style=\"color:#9ECBFF\"> bun</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> deploy:raw</span></span></code></pre>\n<h2 id=\"cuitty-code-and-registry\">Cuitty Code and Registry</h2>\n<p>Cuitty Code can resolve app manifest env, runner env, mirror credentials, webhook signing secrets, OAuth app credentials, deployment keys, Airflow tokens, and Dagger tokens.</p>\n<p>Cuitty Registry can resolve npm publish tokens, Cargo registry tokens, PyPI upload tokens, OCI credentials, artifact storage DSNs, signing keys, and provenance keys.</p>\n<p>Do not resolve Safe refs inside tight package download paths unless explicitly configured.</p>",
  "links_out": []
}