{
  "slug": "code/apps",
  "title": "Cuitty Code Apps",
  "description": "Installable, permission-scoped apps for Cuitty Code.",
  "url": "https://cuitty.com/docs/code/apps",
  "markdown_url": "https://cuitty.com/docs/code/apps.md",
  "json_url": "https://cuitty.com/docs/code/apps.json",
  "frontmatter": {
    "title": "Cuitty Code Apps",
    "description": "Installable, permission-scoped apps for Cuitty Code.",
    "order": 10,
    "section": "Code",
    "updatedAt": "2026-05-24"
  },
  "headings": [
    {
      "depth": 2,
      "slug": "required-services",
      "text": "Required services"
    },
    {
      "depth": 2,
      "slug": "environment-variables",
      "text": "Environment variables"
    },
    {
      "depth": 2,
      "slug": "permissions-model",
      "text": "Permissions model"
    },
    {
      "depth": 2,
      "slug": "common-workflows",
      "text": "Common workflows"
    },
    {
      "depth": 2,
      "slug": "failure-modes-and-recovery",
      "text": "Failure modes and recovery"
    },
    {
      "depth": 2,
      "slug": "related-pages",
      "text": "Related pages"
    }
  ],
  "body_markdown": "Cuitty Code Apps are installable automation units that run against Cuitty Code resources. Apps are owned by a user or organization, published with a versioned manifest, installed into a target owner, and granted only the permissions declared by the app.\n\nApps can target a user, organization, repository, registry namespace, or package. The target decides which SpiceDB relationships are written for the install and which resources the app can read, write, publish to, or operate.\n\n## Required services\n\n- Cuitty Git API for app, install, run, registry, and callback APIs.\n- Cuitty Git frontend for market, install, and settings flows.\n- Cuitty Auth for browser and API authentication.\n- Database for app metadata, installs, grants, and run state.\n- SpiceDB for app visibility, install, grant, owner, and run authorization checks.\n- Airflow for production app execution.\n- Registry artifact storage when apps publish package or image artifacts.\n- Optional object storage for larger bundles, logs, and execution artifacts.\n\n## Environment variables\n\n```bash\nPUBLIC_API_URL=http://localhost:4351\nPUBLIC_CUITTY_AUTH_URL=http://localhost:7705\nAUTH_ISSUER=http://localhost:7705\nAUTH_CLIENT_ID=cuitty-git\nCUITTY_PUBLIC_URL=http://localhost:4350\nCUITTY_GIT_SECRET_KEY=dev-secret-change-me\nSPICEDB_ENDPOINT=http://localhost:50051\nSPICEDB_PRESHARED_KEY=dev-secret\nAIRFLOW_URL=http://localhost:8080\nAIRFLOW_USERNAME=airflow\nAIRFLOW_PASSWORD=airflow\nCUITTY_APP_EXECUTION_MODE=airflow\nCUITTY_APP_RUN_CALLBACK_SECRET=dev-callback-secret\n```\n\nUse deployment-specific secret management for database URLs, SpiceDB keys, Airflow credentials, registry credentials, and callback HMAC secrets.\n\n## Permissions model\n\nThe app listing controls discovery and installation. The installation controls runtime access. Manifest-declared permissions are the upper bound: installers can approve fewer grants, but the API rejects grants that the manifest did not declare.\n\nPublic apps can be discovered by everyone, private apps are visible only to explicit owners or admins, and organization-visible apps are visible to members of the shared organization. Unauthorized callers may receive `404` when the platform must hide private app existence.\n\n## Common workflows\n\n1. Publish an app release from an immutable Git tag.\n2. Review the manifest, docs path, version, requested permissions, and runtime.\n3. Install the app to a user, organization, repository, registry namespace, or package target.\n4. Run app actions through Airflow with a scoped installation token.\n5. Upgrade only after reviewing permission changes.\n6. Uninstall by revoking grants and disabling app-owned schedules.\n\n## Failure modes and recovery\n\n- If SpiceDB is unavailable, security-expanding writes such as app publish and install should fail instead of creating unprotected resources.\n- If Airflow submission fails, the app run should record the error and remain failed or retryable.\n- If Airflow callbacks are missed, reconciliation should poll Airflow and update terminal run state.\n- If an install requests undeclared permissions, reject the install and leave the previous installation unchanged.\n\n## Related pages\n\n- [Code App Market](/docs/code/app-market)\n- [App permissions](/docs/code/app-permissions)\n- [App execution with Airflow](/docs/code/app-execution-airflow)\n- [Authorization with SpiceDB](/docs/code/authz-spicedb)\n- [Operator runbook](/docs/code/operator-runbook)",
  "body_html": "<p>Cuitty Code Apps are installable automation units that run against Cuitty Code resources. Apps are owned by a user or organization, published with a versioned manifest, installed into a target owner, and granted only the permissions declared by the app.</p>\n<p>Apps can target a user, organization, repository, registry namespace, or package. The target decides which SpiceDB relationships are written for the install and which resources the app can read, write, publish to, or operate.</p>\n<h2 id=\"required-services\">Required services</h2>\n<ul>\n<li>Cuitty Git API for app, install, run, registry, and callback APIs.</li>\n<li>Cuitty Git frontend for market, install, and settings flows.</li>\n<li>Cuitty Auth for browser and API authentication.</li>\n<li>Database for app metadata, installs, grants, and run state.</li>\n<li>SpiceDB for app visibility, install, grant, owner, and run authorization checks.</li>\n<li>Airflow for production app execution.</li>\n<li>Registry artifact storage when apps publish package or image artifacts.</li>\n<li>Optional object storage for larger bundles, logs, and execution artifacts.</li>\n</ul>\n<h2 id=\"environment-variables\">Environment variables</h2>\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:#E1E4E8\">PUBLIC_API_URL</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">http://localhost:4351</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">PUBLIC_CUITTY_AUTH_URL</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">http://localhost:7705</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">AUTH_ISSUER</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">http://localhost:7705</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">AUTH_CLIENT_ID</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">cuitty-git</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">CUITTY_PUBLIC_URL</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">http://localhost:4350</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">CUITTY_GIT_SECRET_KEY</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">dev-secret-change-me</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">SPICEDB_ENDPOINT</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">http://localhost:50051</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">SPICEDB_PRESHARED_KEY</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">dev-secret</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">AIRFLOW_URL</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">http://localhost:8080</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">AIRFLOW_USERNAME</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">airflow</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">AIRFLOW_PASSWORD</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">airflow</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">CUITTY_APP_EXECUTION_MODE</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">airflow</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">CUITTY_APP_RUN_CALLBACK_SECRET</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">dev-callback-secret</span></span></code></pre>\n<p>Use deployment-specific secret management for database URLs, SpiceDB keys, Airflow credentials, registry credentials, and callback HMAC secrets.</p>\n<h2 id=\"permissions-model\">Permissions model</h2>\n<p>The app listing controls discovery and installation. The installation controls runtime access. Manifest-declared permissions are the upper bound: installers can approve fewer grants, but the API rejects grants that the manifest did not declare.</p>\n<p>Public apps can be discovered by everyone, private apps are visible only to explicit owners or admins, and organization-visible apps are visible to members of the shared organization. Unauthorized callers may receive <code>404</code> when the platform must hide private app existence.</p>\n<h2 id=\"common-workflows\">Common workflows</h2>\n<ol>\n<li>Publish an app release from an immutable Git tag.</li>\n<li>Review the manifest, docs path, version, requested permissions, and runtime.</li>\n<li>Install the app to a user, organization, repository, registry namespace, or package target.</li>\n<li>Run app actions through Airflow with a scoped installation token.</li>\n<li>Upgrade only after reviewing permission changes.</li>\n<li>Uninstall by revoking grants and disabling app-owned schedules.</li>\n</ol>\n<h2 id=\"failure-modes-and-recovery\">Failure modes and recovery</h2>\n<ul>\n<li>If SpiceDB is unavailable, security-expanding writes such as app publish and install should fail instead of creating unprotected resources.</li>\n<li>If Airflow submission fails, the app run should record the error and remain failed or retryable.</li>\n<li>If Airflow callbacks are missed, reconciliation should poll Airflow and update terminal run state.</li>\n<li>If an install requests undeclared permissions, reject the install and leave the previous installation unchanged.</li>\n</ul>\n<h2 id=\"related-pages\">Related pages</h2>\n<ul>\n<li><a href=\"/docs/code/app-market\">Code App Market</a></li>\n<li><a href=\"/docs/code/app-permissions\">App permissions</a></li>\n<li><a href=\"/docs/code/app-execution-airflow\">App execution with Airflow</a></li>\n<li><a href=\"/docs/code/authz-spicedb\">Authorization with SpiceDB</a></li>\n<li><a href=\"/docs/code/operator-runbook\">Operator runbook</a></li>\n</ul>",
  "links_out": [
    "/docs/code/app-market",
    "/docs/code/app-permissions",
    "/docs/code/app-execution-airflow",
    "/docs/code/authz-spicedb",
    "/docs/code/operator-runbook"
  ]
}