# AGENTS Source: https://docs.superblocks.com/AGENTS # docs-v2 Superblocks external documentation site, powered by Mintlify. Published at `https://docs.superblocks.com`. ## Commands ```bash theme={null} mintlify dev # Local preview at http://localhost:3000 mintlify build # Production build (usually handled by Mintlify deploy pipeline) ``` ## Structure * `getting-started/` - Onboarding and quickstart guides * `integrations/` - Integration-specific documentation * `applications/` - Application building guides (pages, components, queries, workflows) * `admin/` - Admin and organization settings * `enterprise/` - Enterprise features (on-premise, SSO, audit logs) * `components/` - UI component reference * `scripts/` - Client-side JS (dropdown, TOC helpers) * `docs.json` - Mintlify configuration (navigation, theme, redirects, SEO) ## Content Guidelines * All content is Markdown with Mintlify extensions (callouts, tabs, cards, accordions) * Navigation structure is defined in `docs.json` under the `navigation` key * Redirects are defined in `docs.json` under `redirects` * Images go in the appropriate content directory alongside their page * Auto-deploys on merge to `main` ## Org-Wide Standards For cross-repo architecture, security practices, observability, and prompt standards, see the org-level AGENTS.md in `superblocksteam/workspace` at `repos/AGENTS.md`. # Self-serve plans Source: https://docs.superblocks.com/admin/ai-credits Learn how Superblocks Governed Agent Units (GAUs) work, what's included in each plan, and how to purchase additional GAUs ## How GAUs work [Governed Agent Units (GAUs)](/admin/billing-overview#what-is-a-governed-agent-unit) are used across Clark (Superblocks' AI agent) and other governance and AI features. Each AI interaction consumes GAUs based on the complexity of the request. Here are some example prompts and their cost: | User prompt | Work done | GAUs used | | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | Add a header section with title and subtitle | Creates a reusable header component and applies existing page typography styles | 1 | | Change the top navigation background to black | Updates navigation styles and verifies contrast on existing text/icons | 2 | | Connect Salesforce opportunities and show a table + column chart | Explores the data with sample queries in Salesforce, identifies the right object and fields with the user, then implements both a table and chart | 4 | | Build a full sales dashboard from this schema | Generates a step-by-step plan, builds layout/components, connects data, and validates the final app | 8 | ## Included GAUs Teams plans use an **organization-level GAU pool** shared by all builders. You are not charged per builder seat. Additional org-level GAU packs are available for purchase. All GAUs reset monthly. ## GAU packs **Org-level top-ups:** Purchase GAUs that can be shared across all users in your organization | GAUs | Cost per month (Annual plan) | Cost per month (Monthly plan) | | ------------- | --------------------------------------------------- | --------------------------------------------------- | | 100 GAUs | **\$100** /month | **\$125** /month | | 250 GAUs | **\$250** /month | **\$313** /month | | 500 GAUs | **\$500** /month | **\$625** /month | | 1,000 GAUs | **\$1000** /month | **\$1250** /month | | 2,500 GAUs | **\$2500** /month | **\$3125** /month | | Custom volume | [Contact Sales →](mailto:pricing@superblockshq.com) | [Contact Sales →](mailto:pricing@superblockshq.com) | GAU packs are billed in-line with your billing schedule. [Contact sales](mailto:pricing@superblockshq.com) for higher volumes. ## Usage tracking Monitor your organization's GAU usage directly in the Superblocks admin console. You can view: * Current GAU balance and usage trends * Per-user GAU consumption * Per-application GAU consumption * Historical usage patterns * Alerts when approaching GAU limits ### Per-application usage Usage is tracked per-application, giving you granular insight into where GAUs are spent across your organization. This helps you: * Identify which applications consume the most GAUs * Allocate resources and budget effectively across projects * Make informed decisions about optimizing high-usage applications # Audit logs Source: https://docs.superblocks.com/admin/audit-logs Search and filter organization audit events in Superblocks **Audit logs** provide a searchable record of activity in your Superblocks organization. With audit logs, admins get visibility into: * **Builder activity** (edits, deploys, permission changes) * **End-user activity** in your apps * **Integration and platform changes** (credentials, configuration, and other administrative updates) All of this audit data is also available **programmatically** through the [Superblocks MCP server](/admin/mcp-server)—use the Audit capabilities to query the same events from agents, scripts, and other tooling. ## Searching for logs In the [**Audit logs**](https://app.superblocks.com/audit) page, filter by time range, event type, resource, actor, status, and severity. | Control | Purpose | | -------------- | ---------------------------------------------------------------- | | **Search** | Text search over audit events | | **Date range** | Start and end date-time for the events to include | | **Event type** | Limit to one [event type](#event-types), or **All** | | **Status** | Limit by outcome (e.g., Success or Failure), or **All** | | **Severity** | Limit by severity level (e.g., Low+, Medium+, High+), or **All** | | **Resource** | Limit to one or more [resource kinds](#resources), or **All** | | **Actor** | Limit to actions by a specific user, or **Anyone** | You can then view any matching events, and click into an event to see the raw event details. ![Audit logs](https://superblocks-docs.s3.us-east-2.amazonaws.com/assets/audit_logs.png)
Audit event details
## Event types You can filter by the following **Event type** values: * **Account Change** * **Authentication** * **Entity Management** * **User Access** * **App Lifecycle** ## Resources You can filter by **Resource** to focus on events that target a given kind of object. Available values include: * **Agent** * **Application** * **Credential** * **Folder** * **Group** * **Integration** * **Knowledge** * **Organization** * **Permission** * **Repository** * **Role** * **Session** * **Token** * **User** # Billing overview Source: https://docs.superblocks.com/admin/billing-overview How Enterprise dollar-commit billing works: Governed Agent Units, committed spend, and deployed applications Enterprise organizations on the standard **dollar-commit** contract pay against a committed dollar amount for the contract period. Usage shows up in dollars on [Plan & Usage](/admin/plan-and-usage), so you can see how Clark work and deployed apps draw down that commit. This is the experience for customers with a dollar commit with Superblocks. If your organization has a special contract, usage is shown in GAUs instead of dollars in the commitment summary, the usage chart, the usage table (including checkpoint rows), and the deployed applications view. This page covers the concepts. For a walkthrough of the Plan & Usage UI, see [Plan & Usage](/admin/plan-and-usage). To set limits and alerts, see [Spend management](/admin/spend-management). ## What is a Governed Agent Unit? A **Governed Agent Unit (GAU)** measures the amount of secure orchestration, governance, cost optimization, and reliability work Superblocks performs around AI model inference. On a dollar-commit contract, GAU consumption is priced into dollars and counted against your commit and any overage. | Deployment | What's included in the GAU rate | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Superblocks Cloud Prem** | You pay AWS directly for inference, so the GAU rate reflects platform orchestration and governance work only. Model costs are separate and billed by AWS. | | **Superblocks Cloud** | Pricing includes inference, so one rate covers both the model inference and platform work to govern it. | ### Platform work included in each GAU Each GAU covers Superblocks platform work across the following areas: #### Security and governance * **Prompt-injection protection:** Superblocks scans prompts and model interactions for malicious instructions designed to manipulate Clark or gain unauthorized access to company systems and data. * **Isolated sandbox orchestration:** Superblocks runs agent work inside isolated execution environments and manages the lifecycle of each sandbox, including creation, pausing, resuming, and termination. * **Integration authentication and authorization:** Whenever Clark accesses an integration, Superblocks authenticates the connection and verifies that the user and agent are authorized to perform the requested action. * **Application security scanning:** Before deployment, Superblocks performs static and runtime security checks on generated applications to identify vulnerabilities and unsafe behavior. * **Package and supply-chain security:** When packages are installed, Superblocks checks them against vulnerability and malware intelligence to reduce the risk of compromised or malicious dependencies. * **Security agents:** Specialized agents inspect applications for security risks that traditional code scanning may miss, including authorization flaws, unsafe data access, and business-logic vulnerabilities. * **Policy agents:** Organizations can define agents that evaluate applications and agent actions against company-specific security, compliance, architectural, and operational policies. * **Audit logging:** Superblocks records prompts, agent actions, integration calls, policy decisions, and results to provide traceability across the application lifecycle. #### Cost optimization * **Prompt and token caching:** Superblocks reuses eligible prompt and context data to avoid unnecessary model processing and reduce inference costs. * **Context management:** Superblocks determines which information should be retained, summarized, retrieved, or removed so models receive the context they need without repeatedly processing the entire session history. * **Model routing:** Superblocks routes work across frontier and open-source models based on the complexity of the task, balancing output quality, latency, and cost. #### Infrastructure automation and reliability * **Inference failover and retries:** Superblocks detects failed or degraded model requests and manages retries, fallback models, and recovery workflows to keep agent execution moving. * **Execution monitoring:** Superblocks tracks agent progress, errors, tool calls, and intermediate results so long-running tasks can be observed and recovered. * **Database provisioning and migration:** Superblocks provisions application databases inside the customer’s AWS private cloud and manages schema migration across development and production environments. * **Application deployment:** Superblocks packages and deploys applications while applying the required security, infrastructure, and organizational controls. ## Dollar-commit contracts With a dollar-commit Enterprise contract: * Your organization has a **committed dollar amount** for the contract period * **Clark / GAU usage** and **deployed application charges** both count toward that commit and any overage * Plan & Usage shows spend in **dollars**, including a commitment / usage bar for the main contract type * Billing type on usage rows can show **Committed** vs **Overage** when your contract distinguishes them For Teams (self-serve) packs and refills, see [Self-serve plans](/admin/self-serve-plan). ## Enterprise platform license The enterprise platform license provides unlimited platform access, enterprise identity and governance controls, spend management, support, and hands-on onboarding for builders and administrators. * **Unlimited builders and end users:** Create and use unlimited applications without per-seat builder or end-user fees. * **SSO and SCIM:** Connect your identity provider to centralize authentication and automatically provision and deprovision users and groups. * **Bring Your Own Key inference — Cloud-Prem:** Use model inference through your own cloud accounts and credentials, keeping model usage and spend within your cloud environment. * **Application RBAC:** Control who can access each application and what actions they can perform based on assigned roles. * **Platform audit logging:** Maintain a centralized record of administrative activity, access changes, application events, and platform actions. * **Platform Admin MCP:** Allow authorized AI agents and administrative tools to securely manage the Superblocks platform through governed interfaces. * **Spend management:** Set budgets, usage limits, and policies to monitor and control AI and platform consumption across teams. * **Enterprise Support SLA:** Receive priority support with contracted response times and escalation paths for business-critical issues. * **Shared Slack or Microsoft Teams channel:** Collaborate directly with the Superblocks team through a dedicated shared support and coordination channel. * **Forward Deployed Engineer:** Receive part-time hands-on support for platform administration, implementation guidance, builder onboarding, and training. ## Deployed applications Deployed (published) applications incur charges by app-month. On Plan & Usage, the **Deployed Applications** view shows which apps are billed for which months, including **Pending** charges for the current month before the period closes. Superblocks manages deployments, infrastructure, scaling, infrastructure security, incident recovery, and uptime for deployed applications. ## Fully managed AWS Cloud Prem Superblocks can provision, operate, monitor, upgrade, and support the platform inside your AWS account with an enterprise uptime SLA, so you do not need to dedicate internal DevOps resources to managing it. # Code Security Source: https://docs.superblocks.com/admin/code-security/index Secure the code and dependencies in every Superblocks app with supply chain controls, static analysis, and an AI security agent **Code Security** covers the controls Superblocks applies to the code and dependencies that ship in your applications, enabling builders to ship AI-generated code fast and securely without leaving the Superblocks editor. Three layers work together: Check packages at install time, scan again before publish, and continuously monitor published apps for newly disclosed CVEs Deterministic scanning for hardcoded secrets and insecure code patterns at publish time A Superblocks-managed AI reviewer that reasons about your application the way a security engineer would ## When each control runs Think of Code Security as three moments in the app lifecycle. Supply-chain package checks span all three; pre-publish also runs deeper code scans. | Moment | What runs | Where builders or admins see it | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- | | **Install time** | Package CVE and malware checks, plus a **7-day cooldown** on brand-new npm releases | Clark chat when a package is requested | | **Pre-publish** | [Static analysis](/admin/code-security/static-analysis) and dependency scanning, plus the [Security Agent](/admin/code-security/security-agent) (and your [Policy Agents](/admin/policy-agents/index) when configured). These checks go beyond CVEs: secrets, insecure patterns, and application-level risks | Publish readiness checklist and publish detail | | **Continuous** | Ongoing CVE monitoring of **published** apps as new advisories appear | [Security Center](/admin/code-security/supply-chain/cve-detection#security-center) | CVE detection applies whether or not you use the default public registry or configure an optional [private registry](/admin/code-security/supply-chain/private-registries). ## Supply chain * **[CVE detection](/admin/code-security/supply-chain/cve-detection)**: block unsafe installs (with cooldown), re-check dependencies before publish as part of the built-in security scan, and monitor published apps in Security Center. * **[Private registries](/admin/code-security/supply-chain/private-registries)**: route every `npm install` through registries your security and platform teams already trust (for example CodeArtifact, Artifactory, or Nexus), so builders and [Clark](/building-with-clark/index) only install from approved sources. ## Static analysis [Static analysis](/admin/code-security/static-analysis) runs automatically against application source and built artifacts at publish time. It is deterministic and Superblocks-managed: no configuration beyond enabling it and choosing which severities block a deploy. It catches hardcoded secrets, injection-prone patterns, and other issues that can be detected by inspecting code directly. The same built-in security scan also includes dependency scanning for known package advisories on the snapshot being published. ## Security Agent The [Security Agent](/admin/code-security/security-agent) is an AI reviewer that reads the application the way a security engineer would, following data across pages, APIs, and integrations to find issues that pattern matching misses, such as missing authorization on a sensitive endpoint or PII returned in an API response. It runs on Claude, following the approach of Anthropic's open-source [Claude Code security review](https://github.com/anthropics/claude-code-security-review), tuned for the Superblocks execution model so platform-enforced protections are not reported as findings. ## How findings reach builders Every pre-publish Code Security check feeds into the same **publish readiness** checklist. Builders see one view of which checks passed, which are running, and which are blocking their deploy: ```text theme={null} Static Analysis Passed Security Agent Blocked (2 findings) ``` Each item links to a report with findings, evidence, locations, and next actions. Admins choose per check whether findings are **blocking** (publish is prevented until findings are remediated or an admin overrides) or **advisory** (findings are shown but publish proceeds). When a finding is eligible, builders click **Fix with Clark** and Clark remediates it. A remediation attempt never resolves the gate on its own. A fresh run must verify the new application state before publish unblocks. Install-time package blocks appear in Clark chat, not in that checklist. Continuous CVE findings appear in Security Center for admins. ## Audit and RBAC Every run, finding, remediation attempt, escalation, and admin override is recorded as an [audit log](/admin/audit-logs) event, and is available programmatically through the [Superblocks MCP server](/admin/mcp-server). RBAC controls who can configure checks and blocking thresholds, view reports and findings, escalate blocked findings, and force-push past a blocking check. ## Related * [Policy Agents](/admin/policy-agents/index): configure your own AI reviewers for organization-specific policies beyond security * [Knowledge](/building-with-clark/knowledge/index): guide Clark while it writes code, so fewer findings appear at publish time # Security Agent Source: https://docs.superblocks.com/admin/code-security/security-agent An AI security reviewer that reads your application end to end and reports exploitable findings before publish The **Security Agent** is a Superblocks-managed AI reviewer that reads your application the way a security engineer would. Where [static analysis](/admin/code-security/static-analysis) matches known-bad patterns, the agent follows data across pages, APIs, and integrations to reason about whether an issue is actually exploitable in context. It runs on Claude and follows the approach of Anthropic's open-source [Claude Code security review](https://github.com/anthropics/claude-code-security-review), with a Superblocks-specific policy and application context layered on top so platform-enforced protections are not reported as findings. ## What it looks for By default the agent performs a comprehensive security review covering: * Hardcoded secrets, API keys, tokens, and passwords in source code * SQL, code, command, SSRF, and template injection * Cross-site scripting from user-controlled data rendered as raw HTML * Missing or broken authentication and authorization checks * Sensitive data (PII, credentials) logged, leaked in responses, or stored insecurely * Weak or deprecated cryptography * Insecure network configuration: wildcard CORS, disabled TLS verification, open redirects * Insecure deserialization and unrestricted file uploads * API endpoints that return excessive data or expose internal details The agent also reports security concerns that do not fit these categories. It is read-only: it evaluates and reports, and never modifies the application. ### Superblocks-aware analysis The agent receives context about the Superblocks execution model along with the application, which keeps findings grounded: * **Platform authentication and access control.** Users must be authenticated to open a Superblocks app, and each app has its own access control list. The agent does not flag an API for "missing authentication" simply because the API code has no explicit check. It flags authorization issues when an API takes a sensitive identifier from client input instead of reading the authenticated user from server-side context. * **Bindings are not eval.** `{{ }}` bindings are evaluated in a controlled sandbox and are not treated as injection. * **Integrations.** Integration configuration is inspected for leaked credentials and insecure settings. * **Severity reflects exploitability.** Mitigations such as input validation, escaping, or platform-level access control lower severity. Developer comments explaining a deliberate trade-off are acknowledged rather than re-flagged. Raw secret values are never echoed in findings. They are redacted. ## Configuration Admins configure the agent from **Policies** in the dashboard: | Setting | Description | | ---------- | ---------------------------------------------------------------------------------------------------------------------- | | **Name** | Display name shown in publish readiness and run reports | | **Status** | Enabled or disabled | | **Mode** | **Blocking** prevents deploys when findings are present; **Advisory** reports findings without blocking | | **Prompt** | The policy the agent enforces. Leave the Superblocks-managed policy in place, or replace it with your own instructions | Starting from the **General Security Review** template gives you the default policy above as an editable prompt. ## Findings Each finding the agent reports includes: | Field | Description | | ------------------------- | --------------------------------------------------------------------------------------- | | **Title and description** | What the agent found, in plain language | | **Severity** | Critical, high, medium, low, or info, based on actual exploitability | | **Category** | The class of issue, such as a leaked secret or an injection risk | | **Location** | File and line where the issue exists | | **Evidence** | The specific code that triggered the finding, with secrets redacted | | **Suggested fix** | How to resolve the issue | | **Fix with Clark** | Available when Clark can resolve the issue by editing application code or configuration | Findings that require credential rotation, external account changes, infrastructure work, or a human policy decision are marked as not remediable by Clark. ## Remediation flow 1. The agent runs against the application and reports findings in publish readiness 2. The builder clicks **Fix with Clark** on an eligible finding 3. Clark edits the application to resolve it 4. A fresh agent run verifies the new application state. Only a clean result unblocks publish 5. If Clark cannot remediate, the builder escalates to an admin, who can override a blocking finding when appropriate ## Runs and history Every agent run is listed with its status (queued, running, passed, findings, blocked, errored, timed out, canceled), duration, and the findings it produced. Runs are recorded as [audit log](/admin/audit-logs) events. ## Billing The Security Agent consumes GAUs from your organization's shared pool, the same as other Clark AI interactions. Usage appears in your [billing dashboard](/admin/self-serve-plan) under agent usage. ## Related * [Static analysis](/admin/code-security/static-analysis) * [CVE detection](/admin/code-security/supply-chain/cve-detection) * [Policy Agents](/admin/policy-agents/index): agents you author for non-security policies # Static analysis Source: https://docs.superblocks.com/admin/code-security/static-analysis Detect hardcoded secrets and insecure code patterns in AI-generated code before they reach production **Static analysis** is a built-in [Code Security](/admin/code-security/index) check that inspects your application source and built artifacts for security issues before publish. It is deterministic: the same code always produces the same findings. When issues are found, Clark fixes them automatically, and admins control which severity levels block deployment. No configuration beyond enablement is required. Superblocks manages the scanner and normalizes findings into actionable reports. ## What it scans | Category | What it checks | Example findings | | ------------------------ | ------------------------------------------------------- | -------------------------------------------------------------- | | **Leaked secrets** | Source code and built artifacts for exposed credentials | API key hardcoded in a backend query | | **Code vulnerabilities** | Application source for common vulnerability patterns | SQL injection via unsanitized user input, cross-site scripting | Built-asset scanning is the authoritative gate for secrets: it checks the final bundle that would ship to production, not just the source. If a secret makes it into the build output, the scan catches it regardless of how it got there. For dependency and package vulnerabilities, see [CVE detection](/admin/code-security/supply-chain/cve-detection). For issues that require reasoning about application logic rather than pattern matching, see the [Security Agent](/admin/code-security/security-agent). ## When it runs Static analysis runs automatically at **publish time**, after the application is built and before it deploys. The scan evaluates the exact artifact that would ship to production, so there is no gap between what was checked and what was deployed. Builders do not need to trigger scans manually. The scan runs in the background and results appear in the publish readiness checklist. ## Admin controls ### Blocking thresholds Admins configure which severity levels block publish and which are advisory: | Severity | Recommended mode | Rationale | | ------------ | ---------------- | --------------------------------------------------------- | | **Critical** | Blocking | High-confidence issues that must be fixed before deploy | | **High** | Blocking | Significant vulnerabilities that should not ship | | **Medium** | Advisory | Worth reviewing but unlikely to be exploitable in context | | **Low** | Advisory | Informational findings for awareness | These thresholds are configurable per organization. You can adjust them based on your risk tolerance and the maturity of your security program. ### Scope Static analysis applies to all applications in your organization by default. Admins can adjust scope as needed. ## What builders see When a scan completes, builders see findings in their publish readiness checklist: ```text theme={null} Static Analysis Blocked (1 critical secret detected) ``` Clicking into the report shows each finding with: * **What was found**: clear description of the issue * **Where**: file path and location in the application * **Severity**: critical, high, medium, or low * **Fix with Clark**: one-click remediation for eligible findings ### Remediation flow 1. Builder clicks **Fix with Clark** on a finding 2. Clark modifies the application to resolve the issue (e.g., removes a hardcoded secret and references an environment variable instead) 3. A fresh scan runs against the updated application 4. If the finding is resolved, publish unblocks automatically If Clark cannot remediate a finding, the builder can escalate to an admin. Authorized admins can override a blocking finding when appropriate, for example if a finding is a false positive or an accepted risk. ## Visibility and audit trail Every scan is recorded as an [audit log](/admin/audit-logs) entry. Admins can see: * What was scanned and when * What findings were produced * What action was taken (remediated, escalated, overridden) * Which apps have outstanding advisory findings All of this data is available programmatically through the [Superblocks MCP server](/admin/mcp-server), so you can query security findings from agents, scripts, dashboards, or any other tooling. ## Related * [Security Agent](/admin/code-security/security-agent) * [CVE detection](/admin/code-security/supply-chain/cve-detection) * [Private registries](/admin/code-security/supply-chain/private-registries) # CVE detection Source: https://docs.superblocks.com/admin/code-security/supply-chain/cve-detection Block unsafe npm packages at install time with Clark, and monitor published apps for CVEs in Security Center Superblocks checks npm packages against known vulnerability and malware advisories across the app lifecycle: 1. **Install time** - before Clark adds a dependency, including a **7-day cooldown** on brand-new releases 2. **Pre-publish** - dependency scanning as part of the built-in security scan on the snapshot being published (alongside [static analysis](/admin/code-security/static-analysis) and the [Security Agent](/admin/code-security/security-agent), which cover more than CVEs) 3. **Continuous** - Security Center watches **published** apps so newly disclosed CVEs surface even when the app has not changed This is the detection half of [supply chain](/admin/code-security/index) security. [Private registries](/admin/code-security/supply-chain/private-registries) control where packages come from. CVE detection decides which versions are safe to install and stay in production. Install and continuous checks use the same vulnerability index, sourced from [osv.dev](https://osv.dev) (Open Source Vulnerabilities) for the npm ecosystem. Superblocks refreshes that index every hour. Superblocks may also omit advisories that are known unfixable and not applicable to Superblocks apps, so Security Center and install checks stay focused on findings that matter. ## Install-time checks When [Clark](/building-with-clark/index) installs an npm package, Superblocks checks the requested package and version against the osv.dev vulnerability index before the install runs. | Outcome | What happens | | ---------------------------- | --------------------------------------------------------------------------------------------------------- | | **Safe version** | The package installs. If a safer version of the same package exists, Clark installs that version instead. | | **Malware advisory** | The install is blocked. Clark picks a different reputable package that serves the same purpose. | | **CVE with no safe version** | The install is blocked. Clark tries a different package, or builds the capability another way. | ### 7-day cooldown Brand-new npm releases are held back for **7 days** before Superblocks will install them. If Clark requests a version published within that window, Superblocks prefers the newest older version that is outside the cooldown (when one exists). This reduces exposure to compromised or malicious fresh publishes without requiring builders to manage package age themselves. If you named the package in chat and a CVE blocks it, Clark warns you. You can proceed with a short reason, which Superblocks records for the security audit log. Malware blocks have no proceed path. Install-time checks surface in the Clark chat. They are separate from the publish readiness checklist and from Security Center reports. ## Pre-publish dependency scanning At publish time, the built-in security scan re-checks dependencies on the app snapshot being published and contributes findings to the publish readiness checklist (with static analysis). For the full pre-publish story, including secrets, insecure patterns, and AI review, see the [Code Security overview](/admin/code-security/index). ## Security Center **Security Center** gives admins a single view of npm package vulnerabilities across every published application in the organization. Superblocks scans dependencies against known advisories, so newly disclosed CVEs surface even when the app itself has not changed. Security Center lives under **Security** in the dashboard. Admins with **policies:manage** see open npm vulnerabilities across published applications, grouped by app, prioritized by severity, and refreshed as new advisories appear. ### What it shows Security Center with summary, dependency scans, and expanded advisories | Surface | Purpose | | -------------------- | --------------------------------------------------------------------------------------------------- | | **Summary** | How many published apps have vulnerabilities, plus counts by severity (Critical, High, Medium, Low) | | **Dependency scans** | One row per affected published app, with vulnerability count, creator, and status | | **Advisories** | Expand a row for each finding: severity, advisory ID (OSV), package, and detector | The table lists only apps that need attention. Apps with no open vulnerabilities are left out, so an empty table means your published fleet is clean. Each listed app carries one of two statuses: | Status | Meaning | | ---------------- | -------------------------------------------------------------------------------------------------------------- | | **Unresolved** | The deployed commit has open package vulnerabilities | | **Needs review** | No advisory matched, but the exact installed version could not be determined, so the app is not verified clean | For **Unresolved** apps, use **Fix with Clark** or **Unpublish**. For **Needs review**, treat the app as unverified: commit a lockfile (or otherwise pin exact versions) and republish so Superblocks can match advisories against real installed versions. Search by app name, package, or CVE / advisory ID. Filter by severity. A **Low confidence** badge marks findings where Superblocks could not pin an exact version (for example, no lockfile, so the minimum of the declared range was used). ### What is scanned * **Scope:** Published applications with a deployed commit * **Packages:** Dependencies from the deployed commit (`package.json` plus lockfile-resolved versions when available) * **Ecosystem:** npm * **Advisory source:** [osv.dev](https://osv.dev) npm feed * **Detector:** Superblocks Package Scanner Scans evaluate the **deployed** package set (what is live), not an uncommitted local workspace. Findings stay current within the hourly index refresh window as new advisories are published. ### Fix with Clark From Security Center, click **Fix with Clark** on an app or an individual advisory: 1. The app opens in the editor with a pre-built remediation prompt 2. Clark upgrades vulnerable packages to safe versions and keeps the app building 3. Publish (or redeploy) so the deployed package index updates 4. Security Center reflects the remediated packages on the next scan Admins can also **Unpublish** a vulnerable app. Unpublish immediately takes the app offline for all end users; republish (or redeploy) after the fix to restore access. Fix with Clark and Unpublish require deploy access on the target application. ## Package visibility Admins can view npm packages in use across the organization's applications, including versions, through Security Center and the Admin MCP `list_distinct_packages_in_org` tool. This requires the **`policies:manage`** permission (included for Admin and Owner roles by default). This gives security teams a centralized software bill of materials without requiring manual inventory. ## Permissions | Action | Permission | | ----------------------------------------------------------------------- | --------------------------------------- | | Open Security Center, view scans and advisories | `policies:manage` | | List distinct packages across the org (`list_distinct_packages_in_org`) | `policies:manage` | | Fix with Clark / Unpublish from Security Center | Deploy access on the target application | ## Related * [Code Security overview](/admin/code-security/index) * [Private registries](/admin/code-security/supply-chain/private-registries) * [Static analysis](/admin/code-security/static-analysis) * [Audit logs](/admin/audit-logs) # Private registries Source: https://docs.superblocks.com/admin/code-security/supply-chain/private-registries Keep app dependencies secure and compliant by routing package installs through your own trusted npm registries

Who can use this feature?
Organization admins with the appropriate permissions can configure package registry settings.

Private package registries put your organization in control of every npm dependency that ships in a Superblocks app. Instead of pulling from the public npm registry, you point Superblocks at the registries your security and platform teams already trust, so the packages your builders and [Clark AI](/building-with-clark/index) install are the ones you've vetted, governed, and approved. With custom registries you can: * **Meet security and compliance requirements** by keeping package installs inside your own supply chain, with no unreviewed code from the public internet and a clear approval path for what's allowed * **Reduce supply-chain risk** by resolving dependencies from an allowlist-gated or scanned registry (e.g. Artifactory, Nexus, Verdaccio) rather than an open ecosystem * **Reuse what you've already built** by letting builders install your organization's private packages, such as a shared design system, component library, or internal utilities published under your own npm scope (e.g. `@mycompany`) * **Fit your network model** in egress-restricted environments where all traffic must flow through an internal registry Once configured, every `npm install` (in both Edit mode and production builds) flows through your registries. Clark checks package availability against them before attempting an install and gives builders clear, actionable feedback when a package isn't available, so problems surface early instead of at deploy time. ## How registries are matched Superblocks lets you configure two kinds of registry, mirroring how npm resolves packages through an `.npmrc` file: * A **default registry** (unscoped): the fallback for every package that isn't matched by a scoped registry. * Any number of **scoped registries**, each pinned to a single npm [scope](https://docs.npmjs.com/cli/using-npm/scope) (e.g. `@mycompany`). Packages under that scope resolve from the scoped registry; everything else falls through to the default. For example, if a default registry is configured, plus a `@mycompany` scoped registry, `@mycompany/design-system` will resolve from `https://npm.internal.mycompany.com/`, while an unscoped package like `lodash` (or a public-scope package) resolves from the default registry. If no default registry is configured, packages with no matching scoped registry resolve from the public npm registry (registry.npmjs.org). Scoped registries are optional. If you only need a single registry for all packages, configure the default registry and skip the scoped rows. ## Configure the default registry 1. Navigate to **Organization Settings > Package Registry** 2. In the **Default** row under **Package Registries**, enter your **Registry URL**, the full URL of your npm-compatible registry (e.g. `https://artifactory.example.com/api/npm/npm-virtual/`) 3. Optionally enter an **Auth token**, a token with read access to your registry. The token is encrypted at rest and never exposed in the UI after saving 4. Click **Test connection** to verify Superblocks can reach the registry before saving (see [Verify a registry](#verify-a-registry)) 5. Click **Save** | Field | Description | | ---------------- | ------------------------------------------------------------------------------------------ | | **Registry URL** | The full URL of your npm-compatible registry. Must use HTTPS | | **Auth token** | An optional authentication token for the registry. Stored encrypted; redacted after saving | The registry URL must use `https://` and must not embed credentials (e.g. `https://user:pass@host/`); use the **Auth token** field instead. HTTP URLs and inline credentials are rejected to prevent secrets from being sent in cleartext. Before creating your first app, ensure your registry (or registries) serve the [core required packages](#core-required-packages) and their transitive dependencies. The editor will not start if any are missing. ## Add a scoped registry Scoped registries route packages under a specific npm scope to a dedicated registry, while all other packages continue to use the [default registry](#configure-the-default-registry). 1. On the **Package Registry** page, click **Add scoped registry** 2. Enter the **Scope** the registry serves, e.g. `@mycompany` (see [Scope format](#scope-format)) 3. Enter the **Registry URL** and, optionally, an **Auth token**, using the same rules as the default registry 4. Click **Test connection** to verify the registry 5. Click **Save** Saved scoped registries appear as collapsible rows under the default registry, each showing its scope, URL, and connection status. Click a row to expand and edit it. ### Scope format A scope must: * Start with `@` * Use only lowercase letters, digits, `.`, `_`, and `-`, beginning with a letter or digit after the `@` (e.g. `@my-company`, `@team.internal`) * Be unique within your organization; you can configure at most one registry per scope Scopes are normalized to lowercase, matching how npm itself treats them. Uppercase input (e.g. `@MyCompany`) is lowercased automatically. A scope is **fixed once the scoped registry is saved**. To reassign a registry to a different scope, delete the row and add a new one. ## Supported registries Superblocks works with any npm-compatible registry. The tabs below show how to get the **auth token** and **registry URL** for the most common ones, assuming your registry already exists and serves the packages you need. Not every registry can be your **default**. A default registry has to resolve every package a Superblocks app needs, including the \~780 packages in the [core dependency closure](#core-required-packages), so it must proxy or mirror public npm. Registries that only host your organization's own packages must be added as **scoped** registries instead. Verdaccio can be used as a **default or scoped registry**: as the default when its `**` package group proxies an npm uplink, or as a scoped registry when it only hosts your internal packages. Verdaccio issues npm tokens through the npm CLI. Log in as a user with read access to the packages Superblocks will install, then mint a read-only token: ```bash theme={null} npm login --registry https://npm.example.com/ npm token create --read-only --registry https://npm.example.com/ ``` Copy the token value from the command output. If your Verdaccio config grants `access: $all`, reads are anonymous and you can leave **Auth token** blank. Superblocks sends the value in **Auth token** as the npm `_authToken` (a bearer token). Basic-auth credentials in `username:password` form are **not supported**, including the base64-encoded `_auth` value that Verdaccio's htpasswd setup produces. Neither are credentials embedded in the registry URL (`https://user:pass@host/`). Always supply a token minted by `npm token create`. **Registry URL:** your Verdaccio base URL, e.g. `https://npm.example.com/` Verdaccio doesn't always expose `/-/whoami`, so **Test connection** may report **Reachable, token not verified**. The URL is good, but the token is only exercised on a real install. Artifactory can be used as a **default or scoped registry**: point the default at a **virtual** repository that includes a remote (proxy) repository, or use a **local** repository, which serves only packages you publish, as a scoped registry. Use an **identity token** belonging to a service user with read permission on the repository: 1. Log in to Artifactory as the service user 2. Go to **User menu > Edit Profile > Generate an Identity Token** 3. Copy the token, which is shown only once A scoped **access token** with read permission works as well. Don't use the user's password, and don't embed credentials in the URL. **Registry URL:** the npm API path for your virtual repository, e.g. `https://mycompany.jfrog.io/artifactory/api/npm/npm-virtual/` (self-hosted: `https://artifactory.example.com/artifactory/api/npm/npm-virtual/`) Identity and access tokens can expire. If installs fail with `registry authentication failed`, [rotate the token](#manage-auth-tokens). Nexus can be used as a **default or scoped registry**: point the default at a **group** repository that includes an npm proxy, or use a **hosted** repository, which serves only packages you publish, as a scoped registry. To get a token: 1. Enable the **npm Bearer Token Realm** under **Administration > Security > Realms**. Without it, Nexus ignores the `_authToken` Superblocks sends 2. As a service account with read access (`nx-repository-view-npm-*-read`), log in through npm and copy the generated token out of your `.npmrc`: ```bash theme={null} npm login --registry https://nexus.example.com/repository/npm-all/ grep _authToken ~/.npmrc ``` If anonymous read access is enabled on the repository, leave **Auth token** blank. **Registry URL:** your repository URL, e.g. `https://nexus.example.com/repository/npm-all/` If the bearer token realm is disabled, **Test connection** can still report **Reachable** via anonymous access while authenticated installs fail later. Enable the realm before saving a token. CodeArtifact can be used as a **default or scoped registry**: as the default when the repository has a `public:npmjs` external connection (directly or through an upstream), or as a scoped registry when it serves only packages you publish. CodeArtifact tokens come from the AWS CLI. Use an IAM user or role (not the root user) with `codeartifact:GetAuthorizationToken`, `codeartifact:ReadFromRepository`, `codeartifact:GetRepositoryEndpoint`, and `sts:GetServiceBearerToken`: ```bash theme={null} aws codeartifact get-authorization-token \ --domain mycompany --duration-seconds 43200 \ --query authorizationToken --output text ``` Get the matching registry URL with: ```bash theme={null} aws codeartifact get-repository-endpoint \ --domain mycompany --repository superblocks --format npm ``` **Registry URL:** e.g. `https://mycompany-111122223333.d.codeartifact.us-east-1.amazonaws.com/npm/superblocks/` **CodeArtifact tokens expire within 12 hours** (43200 seconds is the maximum), and Superblocks stores the token you paste as a static value, so it can't refresh it for you. When the token expires, installs fail with `registry authentication failed`. Set up [automated token rotation](#rotate-tokens-with-the-api) before builders depend on the registry. GitHub Packages can only be used as a **scoped registry**. It serves only packages named `@OWNER/package` and never proxies public npm, so it can't resolve the [core required packages](#core-required-packages), and using it as the default registry prevents the editor from starting. Set the **Scope** to the GitHub account name, lowercased (e.g. `@mycompany`), and keep a proxying registry (or public npm) as the default. Create a **personal access token (classic)** with the `read:packages` scope, owned by a machine user that has read access to the packages. That token value is the `_authToken`. `GITHUB_TOKEN` and fine-grained tokens don't work here: the former is scoped to a single workflow run, and the latter doesn't cover the npm registry. **Registry URL:** `https://npm.pkg.github.com` The GitLab package registry can only be used as a **scoped registry**, matching your GitLab namespace scope (e.g. `@mycompany`). It serves only packages scoped to its own namespaces and isn't a public npm mirror: request forwarding to npmjs.com is an admin-toggleable Premium/Ultimate self-managed setting, not a substitute for a proxy. Keep a proxying registry as the default. Create a **deploy token** with the `read_package_registry` scope. A group-level deploy token is the most durable option, since it isn't tied to a user. A personal access token with the `api` scope also works. Use the token value as the `_authToken`. **Registry URL:** whichever endpoint matches how your packages are organized: | Endpoint | URL | | -------- | ----------------------------------------------------------------------- | | Instance | `https://gitlab.example.com/api/v4/packages/npm/` | | Group | `https://gitlab.example.com/api/v4/groups//-/packages/npm/` | | Project | `https://gitlab.example.com/api/v4/projects//packages/npm/` | GitLab.com uses the same paths under `https://gitlab.com`. ## Verify a registry Click **Test connection** next to any Registry URL to probe the registry before (or after) saving. Superblocks resolves the host, opens a connection, and reports a status badge on the row: | Badge | Meaning | | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Reachable** | The registry responded and, if a token was supplied, accepted it | | **Reachable, token not verified** | The registry responded but doesn't expose `/-/whoami`, so the token couldn't be validated. Install problems will only surface when Clark or a build job actually installs a package | | **Unreachable** (or a specific error) | The probe failed. See the reason below the field | Common failure reasons: | Reason | Meaning | | ------------------------------------------------------------------------ | ------------------------------------------------ | | Couldn't reach the registry | The host could not be resolved or connected to | | The registry returned an invalid TLS certificate | TLS/certificate validation failed | | The registry rejected your auth token | Authentication failed. Check the token | | This registry requires authentication (supply an auth token and re-test) | The registry needs a token but none was provided | | This URL doesn't look like an npm registry | The endpoint didn't respond like an npm registry | | The registry took too long to respond | The probe timed out | | A network proxy blocked the request | An outbound proxy blocked the connection | When you edit a saved registry's URL, the stored auth token is **not** reused against the new URL. For security, a stored token is only ever sent to its original host. Enter a new token (or **Clear token**) before saving a URL change. ## Manage auth tokens Auth tokens are optional and are sent to the registry as the npm `_authToken`. Leave the field blank for registries that don't require authentication. * Tokens are **stored encrypted at rest** and are **never retrievable** from the dashboard after saving; the field shows only a redacted preview. * To **rotate** a token, enter a new value and save. * To **remove** a stored token, click **Clear token** and save. ### Rotate tokens with the API Registries that issue short-lived tokens, such as [AWS CodeArtifact](#supported-registries) with its 12 hour maximum lifetime, need the stored token refreshed regularly. Rather than pasting a new value by hand, rotate it programmatically on a schedule (for example a cron job in CI, or an EventBridge-triggered Lambda) using the Superblocks npm registry API. Authenticate the calls with the **personal API key** of a user who has permission to update package registries, sent as a bearer token. Copy it from **Personal Settings > API Key** (see [Access tokens](/admin/org-administration/auth/access-tokens#personal-api-key)). Org-level access tokens don't work for these endpoints. For automation, use the key of a dedicated service user rather than an individual's, so rotation keeps working when someone's permissions or employment change. First list your registries to find the ID of the one to update: ```bash theme={null} curl --location --globoff 'https://.superblocks.com/api/v1/organizations//npm-registry' \ --header 'Authorization: Bearer ' ``` Then `PUT` the new token, passing the registry URL along with it: ```bash theme={null} curl --location --globoff --request PUT 'https://.superblocks.com/api/v1/organizations//npm-registry/' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' \ --data '{ "registryUrl": "", "token": "" }' ``` Schedule your rotation job comfortably inside the token lifetime, e.g. every 6 hours for a 12 hour token, so a single failed run doesn't leave you with an expired token. Registry IDs are stable, so you only need to look them up once. Always send `registryUrl` together with the new `token`. A stored token is only ever sent to the host it was saved against, so changing one without the other can leave the registry unauthenticated. ## Network requirements For Superblocks Cloud (SaaS) organizations, your registry must be reachable from Superblocks' infrastructure. The **Network requirements** section on the Package Registry page lists the source **egress IPs** Superblocks connects from; your registry must accept **TCP/443** from these addresses. Use **Copy** or **Copy all** to add them to your registry's or firewall's allowlist. The Network requirements section only appears for SaaS deployments where egress IPs are published. [Cloud-prem](/enterprise/cloud-prem/aws) and self-hosted deployments own their own network path to the registry, so no allowlist is shown. ## Allow install scripts Separately from registry configuration, admins can control whether npm packages are allowed to run post-install scripts. This is an organization-wide setting that applies to all package installs regardless of which registry is configured. Some npm packages run post-install scripts during installation. For example, `sharp` and `better-sqlite3` compile native binaries. Disabling install scripts reduces your supply-chain attack surface by preventing arbitrary code execution at install time, but packages that rely on lifecycle scripts may fail to build. Toggle **Allow packages to run post-install scripts** on the Package Registry page based on your organization's security posture: | Setting | Behavior | | --------------------- | ------------------------------------------------------------------------------------------ | | **Enabled** (default) | Packages can run post-install scripts normally | | **Disabled** | All `npm install` commands include `--ignore-scripts`, blocking lifecycle script execution | ## How Clark interacts with your registry When a builder asks Clark to install a package, Clark checks your configured registry before attempting the install: 1. Clark queries your registry to confirm the package is available 2. If the package is found, Clark proceeds with the install 3. If the package is **not found** in your registry, Clark explains the situation and suggests the builder contact their admin to add the package to the registry's approved list This ensures Clark is aware of your registry configuration and can give builders clear feedback when a package install fails. ### Error messages When a package install fails, Clark provides a structured explanation based on the failure type: | Error | Meaning | | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | **Package not in registry** | The requested package is not available in your organization's registry. Ask your admin to add it to the approved package list | | **Registry authentication failed** | The configured auth token is invalid or expired. An admin needs to update the token in Package Registry settings | | **Registry unreachable** | The registry could not be reached. Check network connectivity and registry availability | ## Enforcement model Superblocks synthesizes an `.npmrc` from your configuration (a top-level `registry=` line for the default registry plus one `@scope:registry=` line per scoped registry) and uses it for all Clark-triggered installs across Clark, the dev server, and the build pod. A package under a configured scope always resolves from that scope's registry; everything else resolves from the default. Clark also checks package availability against the matching registry before attempting installs. For [cloud-prem](/enterprise/cloud-prem/aws) customers who own their network infrastructure, you can combine the Package Registry configuration with network-level controls (e.g. VPC egress rules, NetworkPolicy) that block traffic to `registry.npmjs.org` for full enforcement in egress-restricted environments. ## Core required packages Every Superblocks application ships with a fixed set of npm dependencies. All of these must be resolvable from your registry, or the editor will not start. There are two tiers: * **Platform-critical**: the editor, dev server, and build pipeline require these to function. Clark will never suggest removing them; the only fix for a missing one is for an admin to mirror it into the registry. * **Template defaults**: included in new apps (e.g. Radix UI, Lucide, Recharts). Clark can refactor these away if a builder asks, but they must be available when an app is first created. ### Platform-critical packages These packages cannot be removed or replaced. If any are missing from your registry, the editor will fail to start and Clark cannot work around it. #### `@superblocksteam/*` scoped packages All packages under the `@superblocksteam` scope are platform-owned and protected. These are published to the public npm registry (`registry.npmjs.org`). They resolve through your **default** registry unless you add a scoped registry for `@superblocksteam`. If you do, that registry must serve every package below, or the editor will not start. | Package | Role | | ---------------------------------- | -------------------------------------------------------- | | `@superblocksteam/library` | Core runtime library (component model, state, evaluator) | | `@superblocksteam/sdk-api` | SDK API type definitions | | `@superblocksteam/library-shared` | Shared types consumed by the library and platform | | `@superblocksteam/shared` | Platform-wide shared types and protobuf definitions | | `@superblocksteam/types` | Generated protobuf type bindings | | `@superblocksteam/sabs-types` | Build service type definitions | | `@superblocksteam/fast-deep-equal` | Deep-equality utility | | `@superblocksteam/cli` | Official Superblocks CLI (local dev, resource sync) | | `@superblocksteam/iso-currency` | Currency formatting and data | #### Unscoped platform packages | Package | Role | | ------------------- | ------------------------------------ | | `react` | React runtime | | `react-dom` | React DOM renderer | | `react-router` | App page routing | | `vite` | Dev server and production build tool | | `typescript` | Type checking in the build pipeline | | `@tailwindcss/vite` | Tailwind CSS Vite plugin | | `tailwindcss` | Tailwind CSS framework | ### Full dependency closure A newly created app installs approximately 780 npm packages (direct + transitive). The exact set depends on your Superblocks version. If your registry is configured as a remote proxy, it will automatically fetch transitive dependencies on cache miss. Ensure the platform-critical packages listed above are reachable through your proxy, and the rest will resolve automatically. The first app creation may be slower than usual while the cache warms. If your registry requires explicit approval for every package, you need the full dependency closure. Download the complete package list and feed it to your approval pipeline: Download superblocks-core-packages.json This JSON file lists all \~780 packages with their versions. Use it to verify your registry covers every required dependency. Approximately 52 of these packages are **platform-specific optional binaries** (`@esbuild/linux-x64`, `@rollup/rollup-darwin-arm64`, etc.). npm only installs the ones matching the target platform, but your registry must serve the binaries for every platform where Superblocks runs. Package versions and transitive dependencies may change between Superblocks releases. Use the [Superblocks MCP server](/admin/mcp-server) to query packages currently in use across your organization for the latest inventory. ## Package inventory Admins can list the distinct npm packages in use across all applications using the [Admin MCP](/admin/mcp-server) tool `list_distinct_packages_in_org`. This requires the **`policies:manage`** permission (included for Admin and Owner roles by default; assignable to other roles). * **Registry reconciliation**: compare installed packages against what your private registry serves to find gaps before they cause install failures * **Audit and compliance**: maintain visibility into your organization's npm dependency footprint * **Migration planning**: identify which apps need attention when tightening registry policies Ask your AI coding agent: ```text theme={null} What npm packages are in use across my Superblocks organization? ``` ## Troubleshooting The requested package exists on public npm but has not been added to your private registry. If your registry is a **pull-through cache** (e.g. Artifactory configured as a remote proxy), the package should appear automatically on first request. If your registry uses a **curated allowlist**, your security team needs to approve and mirror the package before it can be installed. The auth token saved in Package Registry settings is invalid or expired. Navigate to **Organization Settings > Package Registry**, enter a fresh token, and save. Tokens from registries like Artifactory and Nexus may have expiration policies. Coordinate with your registry administrator on rotation schedules. Superblocks could not reach your registry. Common causes: * The registry URL is incorrect or has a typo * The registry is behind a firewall that does not allow traffic from Superblocks infrastructure * The registry service is temporarily down Verify the URL is correct and that your registry is accessible from the network where Superblocks runs. For [cloud-prem](/enterprise/cloud-prem/aws) deployments, ensure the Superblocks data plane has network connectivity to your registry. The editor requires approximately 780 npm packages (direct + transitive) to boot a new 3.0 app. If any are missing from your registry, the dev server will fail to start. Check the [core required packages](#core-required-packages) section and ensure all platform-critical packages and their transitive dependencies are available. For pull-through caches, the first app creation may be slower than usual while packages are fetched on cache miss. Package resolution is matched by npm scope. Confirm the package name's scope exactly matches a configured scoped registry (e.g. `@mycompany/utils` requires a `@mycompany` scoped registry). Packages whose scope has no dedicated registry (and all unscoped packages) resolve from the [default registry](#configure-the-default-registry). Scopes are case-insensitive and stored lowercase, so `@MyCompany` and `@mycompany` are treated as the same scope. A scope is fixed once a scoped registry is saved. To move a registry to a different scope, delete the existing row and [add a new scoped registry](#add-a-scoped-registry) with the correct scope. Packages like `sharp`, `better-sqlite3`, and `node-canvas` require post-install scripts to compile native binaries. If you disabled **Allow packages to run post-install scripts**, these packages will fail to build. Either re-enable install scripts, or work with your security team to pre-build and publish these native packages as pre-compiled binaries in your registry. ## Related * [CVE detection](/admin/code-security/supply-chain/cve-detection) * [Code Security overview](/admin/code-security/index) # Manage environments & data tags Source: https://docs.superblocks.com/admin/environments Create data tags and control which data can be accessed in each environment

Who can use this feature?
Users with the profiles:manage permission. This permission is included in the built-in Owner and Admin roles

Superblocks has three built-in **environments** that map to your development lifecycle: | Environment | Description | | -------------- | -------------------------------------------- | | **Edit** | Where developers build your apps | | **Preview** | Where changes are reviewed before going live | | **Production** | Where your live applications run | **Data tags** let you tag different data segments — such as **Staging**, **Production**, or **us-east** — and control which environments each tag is allowed in. Environments page Once created, data tags are associated with [integration configurations](#configure-integration-credentials) and [data plane deployments](/enterprise/hybrid-architecture/deployment/multiple_environments), which are covered below. Your Superblocks account comes with two built-in data tags, **Development** and **Production**. ## Create a data tag Admins can create new data tags to represent different data environments, regions, or stages. To add a data tag: 1. Navigate to the **[Environments](https://app.superblocks.com/environments)** page under **Organization Settings** 2. Click **Add Data Tag** 3. Provide a unique name and key for your data tag 4. Select which environments (Edit, Preview, Production) this data tag is allowed in 5. Click **Create** Create a data tag

Each data tag has a unique alphanumeric key. The key can be customized when creating the data tag but cannot be changed after creation to prevent references from breaking.

### Environment assignment When creating or editing a data tag, you decide which environments it can be used in. This gives admins control over data access: * A tag allowed only in **Edit** and **Preview** keeps that data source out of production * A tag allowed only in **Production** ensures production credentials are never used during development * A tag allowed in all three environments can be used anywhere Once you've created a data tag, you can start: * [Configuring integration credentials](#configure-integration-credentials) * [Using data tags](/development-lifecycle/build/data-tags) in Applications * [Deploying the Superblocks data plane to multiple environments](/enterprise/hybrid-architecture/deployment/multiple_environments) ## Configure integration credentials In Superblocks, integrations can have multiple configurations to connect to different database instances or API servers. Each configuration is linked to one or more data tags. When you create a new integration, Superblocks automatically generates two configurations: | Configuration | Data tags included | Description | | ---------------------------- | ------------------------------------------------------------------------ | -------------------------------- | | **Non-Production** (Default) | All data tags where **none** of their allowed environments is Production | Safe for development and testing | | **Production** | All data tags where **at least one** allowed environment is Production | Isolated production credentials | You can add additional configurations as needed. To update or add configurations: 1. Navigate to [Integrations](https://app.superblocks.com/integrations) and search for your integration or create a new one 2. To add a configuration, click the ➕ icon for "Add new configuration" and select the data tag(s) 3. Fill out the configuration form with values specific to the selected data tags 4. Click **Test Connection** to verify connectivity 5. **Create** or **Save** your changes Default integration configurations ## Using data tags For details on how to use data tags in your Applications, see [Using data tags](/development-lifecycle/build/data-tags).

Data tags were previously called profiles. The core concept is the same — admins now have more control over which data tags are allowed in each environment.

# Admin MCP Source: https://docs.superblocks.com/admin/mcp-server Connect AI coding agents to administer your Superblocks org via the Model Context Protocol The Admin MCP server lets AI coding agents (Cursor, Claude Code, Windsurf, and others) administer your Superblocks organization directly. Agents can list applications, manage integrations, deploy apps, manage access control, and more — all through the [Model Context Protocol](https://modelcontextprotocol.io/). Looking to build, edit, and publish apps conversationally from tools like Claude and Slack? See the [Builder MCP](/building-with-clark/builder-mcp). The Admin MCP on this page is for administering your org from AI coding agents. ## Quickstart Connect to the hosted Superblocks MCP server — no install required. You'll need your Superblocks API token, which you can find in [Personal Settings > API Key](https://app.superblocks.com/personal-settings#apiKey). Install MCP Server Click the button to install, then replace `YOUR_TOKEN` with your API token in **Cursor Settings > MCP**. Or add it manually: ```json theme={null} { "mcpServers": { "superblocks": { "url": "https://app.superblocks.com/mcp", "headers": { "Authorization": "Bearer " } } } } ``` Run this command in your terminal: ```bash theme={null} claude mcp add --transport http \ --header "Authorization: Bearer " \ superblocks https://app.superblocks.com/mcp ``` Point your MCP client at the following URL with an `Authorization` header: ``` URL: https://app.superblocks.com/mcp Header: Authorization: Bearer ``` ## What can the MCP server do? Once connected, AI agents can use the following capabilities through natural language: | Category | Examples | | ------------------- | ------------------------------------------------------------------------------------------------------- | | **Applications** | List apps, view structure, check commit history, deploy, undeploy | | **Integrations** | List, create, update, and delete integrations | | **Access control** | View and manage application, workflow, and job permissions | | **Role management** | Assign and update org-level roles for users and groups | | **Organization** | View org summary, list members, manage builder seats | | **Folders** | Create, update, and delete folders | | **Audit** | Query audit events and compute aggregated metrics | | **Chat history** | Retrieve Clark AI conversation history for any application | | **Billing** | View plan summary and usage | | **Supply chain** | List distinct npm packages across the org (`list_distinct_packages_in_org`; requires `policies:manage`) | | **Knowledge** | List and view Knowledge entries | ## Alternative: Local MCP server If you prefer to run the MCP server locally, you can use the CLI-based setup instead. This requires Node.js 22+ and an API token. Run the following command, replacing `` with your Superblocks API key. You can find your API key in [Personal Settings](https://app.superblocks.com/personal-settings#apiKey). ```bash theme={null} npx -y @superblocksteam/mcp-server login --token ``` Run the setup command for your IDE: ```bash theme={null} npx -y @superblocksteam/mcp-server setup --client cursor ``` This writes the MCP server configuration to `~/.cursor/mcp.json`. ```bash theme={null} npx -y @superblocksteam/mcp-server setup --client claude ``` This writes the MCP server configuration to `~/.claude.json`. ```bash theme={null} npx -y @superblocksteam/mcp-server setup ``` This prints the JSON configuration to stdout. Copy it into your MCP client's configuration file. Restart your IDE to pick up the new MCP server configuration. You should see **superblocks** listed as a connected MCP server. If you already have the [Superblocks CLI](/building-with-clark/developing-apps-in-code) installed, you can set up the local MCP server through it instead: ```bash theme={null} superblocks login superblocks mcp setup --client cursor ``` Use `--dry-run` to preview the configuration without modifying any files: ```bash theme={null} npx -y @superblocksteam/mcp-server setup --client cursor --dry-run ``` ## Troubleshooting Verify your API token is correct. You can find or regenerate it in [Personal Settings > API Key](https://app.superblocks.com/personal-settings#apiKey). Make sure the `Authorization` header uses the `Bearer` prefix: ``` Authorization: Bearer sb_xxxxxxxxxx ``` If the token was recently regenerated, update it in your MCP client configuration and restart your IDE. Verify the server starts correctly by running it directly: ```bash theme={null} npx -y @superblocksteam/mcp-server --help ``` If you see the usage text, the server is installed correctly. Restart your IDE and check that the MCP server appears in your IDE's MCP server list. Re-run the login command to refresh your token: ```bash theme={null} npx -y @superblocksteam/mcp-server login --token ``` Your token is stored at `~/.superblocks/auth.json`. You can verify it exists: ```bash theme={null} cat ~/.superblocks/auth.json ``` The local MCP server requires Node.js 22 or later. Check your version: ```bash theme={null} node --version ``` The hosted server at `app.superblocks.com/mcp` has no local requirements. # Access tokens Source: https://docs.superblocks.com/admin/org-administration/auth/access-tokens Superblocks has several integration options that require access tokens or API keys: * **[Superblocks CLI](https://www.npmjs.com/package/@superblocksteam/cli)** - [Source control](/development-lifecycle/version-control/connect-to-git) your Superblocks tools and [edit apps in code](/building-with-clark/developing-apps-in-code) with the Superblocks command line interface. * **[Import](https://github.com/superblocksteam/import-action) and [Export](https://github.com/superblocksteam/export-action) Actions** - Sync changes back to Superblocks using GitHub Actions and GitLab Pipelines. * **[SCIM API](/admin/org-administration/auth/scim)** - Manage Superblocks users and groups programmatically. * **Embed Session API** - Lets you request session tokens for embedded users to grant them access to your embedded applications. ## Personal API key The [Superblocks CLI](https://www.npmjs.com/package/@superblocksteam/cli) and CI actions require a personal API key for authorization. The operations you can perform is tied to your personal permissions within the Superblocks platform. To access your personal API key: 1. Click your avatar in the upper-left corner of the home page and click **Personal Settings** 2. On the left nav, click **API Key** 3. Click the copy icon to copy your API key ## API authentication The [SCIM](/admin/org-administration/auth/scim) and Embed Session API both require org-level access tokens. The set of operations the token can perform is based on the **Token type** set when creating the token. * **Org Admin** - used by the [SCIM API](/admin/org-administration/auth/scim) and has permission to manage org settings, users, and groups * **Embed** - create and manage authenticated session tokens for Embedded Apps users Only organization Admins can create and delete org-level access tokens. ### Creating an access token 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. On the left nav, click **Access Tokens** 3. Click **+Create token** 4. In the **Name** field give your token a descriptive name 5. Select an **Expiration** date, or use the default 90 day expiration. 6. Set the **Token type** that you want 7. Click **Create** Your access token is visible one time, immediately after you create it. If you leave or refresh the page where the token is displayed, it will be obscured and no longer visible. You must copy and store new access tokens somewhere secure before you leave the creation page, or you will lose access to the token. ### Deleting an access token Deleting an access token removes it from your account. This is an irreversible action and a deleted token cannot be recovered. For this reason, we recommend creating a new access token and update anywhere you're calling Superblocks APIs, before deleting the token. 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. On the left nav, click **Access Tokens** 3. In the table of access tokens, select Remove next to the token you'd like to delete 4. Confirm in the browser alert # Entra ID SCIM setup Source: https://docs.superblocks.com/admin/org-administration/auth/scim/azure-ad Instructions for setting up SCIM provisioning using Azure Entra ID as an IdP ## Features The following provisioning features are supported when integrating with Entra ID: * Create users in Superblocks * Remove users in Superblocks when they do not require access anymore * Keep user attributes synchronized between Entra and Superblocks * Provision groups and group memberships in Superblocks ## Prerequisites The scenarios outlined in this tutorial assumed that you already have the following items: * An Entra tenant * A user account with permission to configure provisioning (for example, Application Administrator, Cloud Application administrator, Application Owner, or Global Administrator) * A Superblocks organization on the Enterprise plan * A user account in Superblocks with Admin permissions ## Setup 1. Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com/) 2. Navigate to **Identity** → **Applications** → **Enterprise applications** 3. Select your Superblocks SSO app or select **+ New application** → **+ Create your own application** 4. In the app management screen, select **Provisioning** in the left panel 5. Set the **Provisioning mode** to **Automatic** 6. Configure credentials as follows: | Field | Value | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Tenant URL | **US**: [https://app.superblocks.com/scim/v2](https://app.superblocks.com/scim/v2)
**EU**: [https://eu.superblocks.com/scim/v2](https://eu.superblocks.com/scim/v2) | | Secret token | [Access token](/admin/org-administration/auth/access-tokens) with Org Admin privileges | 7. Test the connection and click **Save** 8. Optionally, [configure user attributes](#configure-user-attributes) 9. Turn the **Provisioning Status** to **On** 10. Select the **Users and groups** tab and assign the users or groups you want to sync ## Configure user attributes Certain user attributes in Entra can by synced to your Superblocks users' profiles. ### Supported user attributes The Superblocks SCIM API currently supports the following attributes: | SCIM User Attribute |
Superblocks User Attribute
| Description | | ------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `emails` | `Global.user.email` | Email identifier used to log in to Superblocks. | | `displayName` | `Global.user.name` | The text shown in Superblocks when referring to the user. | | `name.givenName` | `Global.user.name` | First name of the user. Concatenated with `name.familyName` if `displayName` is not provided. | | `name.familyName` | `Global.user.name` | Last name of the user. Concatenated with `name.givenName` if `displayName` is not provided. | | `groups` | `Global.user.groups` | List of groups to which the user belongs. | | `active` | N/A | Disables the user when set to `FALSE` | | `role` | N/A | The user's [**organization role**](/admin/org-administration/org-roles). Defaults to `null`. If not set, the [default role for the organization](/admin/org-administration/org-roles/using-org-roles#setting-default-role) will be used. | ### Create custom role attribute All of the supported attributes listed above except for `role` are supported by default in Entra ID. You can manage a user's [**organization role**](/admin/org-administration/org-roles) via SCIM by configuring a custom attribute in Entra. To do so: 1. Go to your app's **Provisioning** page 2. Expand the **Mapping** section 3. Click on the **User** mapping 4. Scroll to the bottom of the page and click **Show advanced options** 5. Click **Edit attribute list for customappsso** 6. Add the following new attribute to the list | Field | Value | | ----- | ----------------------------------------------------------------- | | Name | `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:role` | | Type | String | 7. Click **Save** 8. Back on the User mapping page, click **Add New Mapping** 9. Create a mapping with the **Target mapping** set to the role attribute just configured 10. Click **Save** Now when users are provisioned or attributes updated, their [organization role](/admin/org-administration/org-roles) in Superblocks will be set based on the role assigned in Entra. # Manage users and groups with SCIM Source: https://docs.superblocks.com/admin/org-administration/auth/scim/index Automatically manage users and groups from an external user directory using the System for Cross-domain Identity Management (SCIM) standard in Superblocks SCIM provisioning lets Organization Admins manage team members more efficiently, including: * Invite users to your Superblocks team * Deactivate users in your organization * Update user details, including name and email * Create, rename, and delete Groups in Superblocks * Assign and unassign users from Groups With user and group management automated using your identity provider, you can be sure your team always has access to the internal tools they need in Superblocks. ## Set up provisioning Your SCIM provisioning set up will vary depending on the identity provider you use. For instructions select your provider below: * [Okta](/admin/org-administration/auth/scim/okta) * [Microsoft Entra ID](/admin/org-administration/auth/scim/azure-ad) * OneLogin (Coming soon) # Okta SCIM setup Source: https://docs.superblocks.com/admin/org-administration/auth/scim/okta Instructions for setting up SCIM provisioning using Okta as an IdP **Notes** * If you are setting up SCIM after assigning users to a Superblocks SSO app, be sure to run a [**full import**](#import-existing-users) to link the existing assigned user to the Superblocks user * If your Superblocks SSO app uses [**OpenID Connect App**](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_oidc.htm), you'll need to create a separate provisioning-only app to handle SCIM. You'll assign users/groups to both of these applications. Learn more about how to [Add a provisioning only app](#add-a-provisioning-only-app) ## Features The following provisioning features are supported when integrating with Okta: * **Push New Users**: New users created through Okta will also be created in the company's Superblocks organization. * **Push User Deactivation**: Deactivating a user through Okta will deactivate the user from the company's Superblocks organization. * **Reactivate Users**: Reactivating a user through Okta will reactivate the user in Superblocks. * **Push Profile Updates**: Updates made to the user's profile through Okta will be pushed to Superblocks. * **Import New Users**: New users created in Superblocks will be downloaded and turned into new AppUser objects, for matching against existing Okta users. * **Group Push**: Groups and their members can be pushed to Superblocks. ## Setup If your SSO app uses [**OpenID Connect**](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_oidc.htm), you'll need to create a separate SCIM app. Follow instructions to [create a provisioning only app](#add-a-provisioning-only-app), then come back to [configure SCIM](#configure-scim). ### Configure SCIM 1. From the Okta admin console, locate your **Superblocks** SSO App 2. Go to the **General** tab, click **Edit** on the **App Settings** 3. Check the box **Enable SCIM Provisioning** and click **Save** Enable SCIM on Okta Application 4. Go to the newly enabled **Provisioning** tab 5. Next to **SCIM Connection** click **Edit**. Configure the connection as follows: | Field | Value | | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SCIM connector base URL | **US**: [https://app.superblocks.com/scim/v2](https://app.superblocks.com/scim/v2)
**EU**: [https://eu.superblocks.com/scim/v2](https://eu.superblocks.com/scim/v2) | | Unique identifier field for users | email | | Supported provisioning actions | Select all of the provisioning actions | | Authentication Mode | HTTP Header | | Authorization | [Access token](/admin/org-administration/auth/access-tokens) with Org Admin privileges | 6. Test the connection and click **Save** 7. You should see two new settings **To App** and **To Okta**. Click **To App** 8. Click **Edit** and configure your provisioning options. Note: Sync Password is not supported Okta SCIM configuration 9. Click **Save** 10. Optionally, configure attribute mappings to [assign user roles via SCIM](#manage-user-roles-with-scim) ### Add a provisioning only app If your Superblocks SSO app in Okta uses [**OpenID Connect**](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_oidc.htm), you'll need to set up a separate app for SCIM. The easiest way to do this is to set up a separate [**Secure Web Authentication (SWA) App**](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_swa.htm). This app **will not** be used by your users to sign-in to Superblocks, it will just be used for provisioning/group management. To configure an SWA app: 1. From the Okta admin console, click **Applications** → **Applications** 2. Click **Create App Integration** 3. Select **SWA - Secure Web Authentication** 4. Name the app and enter `https://app.superblocks.com` as the login URL 5. Click **Finish**. You can now [continue to configure SCIM for Superblocks](#configure-scim) Note that users will not be able to log in through this app so you should make sure you're not showing this app to users on the Okta launch page. ## Import existing users With SCIM configured, you should run an import of existing users from your Superblocks organization to Okta so you can link your Okta users to their Superblocks account. 1. From your Superblocks SCIM app in Okta, click on the **Import** tab. 2. Click **Import Now** which will import all users from your existing Superblocks account. 3. Choose how you want Okta to import each user. Options include: * Link to **EXACT Okta user match**: links the Superblocks user to an existing user in Okta. * Link to **NEW Okta user**: creates a new user in Okta and links the Superblocks user to the new user * **IGNORE this user for now**: leave the user in Superblocks and doesn't link them to an Okta user. Superblocks users that are not linked to a user in Okta will need to be managed from Superblocks. Learn more about [Managing Users](#manage-superblocks-users) Okta import users 4. Click **Confirm Assignments** to finish the import ## Configure user attributes Certain user attributes in Okta can by synced to your Superblocks users' profiles. ### Supported user attributes The Superblocks SCIM API currently supports the following attributes: | SCIM User Attribute |
Superblocks User Attribute
| Description | | ------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `emails` | `Global.user.email` | Email identifier used to log in to Superblocks. | | `displayName` | `Global.user.name` | The text shown in Superblocks when referring to the user. | | `name.givenName` | `Global.user.name` | First name of the user. Concatenated with `name.familyName` if `displayName` is not provided. | | `name.familyName` | `Global.user.name` | Last name of the user. Concatenated with `name.givenName` if `displayName` is not provided. | | `groups` | `Global.user.groups` | List of groups to which the user belongs. | | `active` | N/A | Disables the user when set to `FALSE` | | `role` | N/A | The user's [**organization role**](/admin/org-administration/org-roles). Defaults to `null`. If not set, the [default role for the organization](/admin/org-administration/org-roles/using-org-roles#setting-default-role) will be used. | ### Create custom role attribute All of the supported attributes listed above except `role` are supported by default in the Okta user profile. You can manage a user's [**organization role**](/admin/org-administration/org-roles) via SCIM by configuring a custom attribute in Okta. Roles can be assigned to users, or you can scale role management by assigning roles based on the Okta group a user is in. To learn more about how Okta manages syncing attributes via SCIM, read Okta's [Attribute Mapping](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-about-attribute-mappings.htm#Okta) documentation. To create a custom attribute for your Superblocks user roles: 1. Go to your Superblocks SCIM app in Okta 2. Click on the **Provisioning** tab 3. In the **To App** settings, scroll down to the section labeled **Superblocks Attribute Mappings** 4. Click **Go to Profile Editor** 5. Click **Add Attribute** 6. Fill in the attribute configuration as follows: | Field | Value | | ------------------ | ------------------------------------------------------------ | | Data type | string | | Display name | Superblocks Role (customizable) | | Variable name | `superblocks_role` (customizable) | | External name | `role` | | External namespace | `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User` | | Enum | Checked | 7. In the **Attribute members** list include the following: | Display name | Value | | ------------ | ----------- | | Owner | `owner` | | Admin | `admin` | | Developer | `developer` | | End-user | `end_user` | The `value` field should correspond to the `key` of [organization role](/admin/org-administration/org-roles) you want to assign. You can find the key of any of your custom roles, by going to the [Roles & Permissions](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-about-profiles.htm#App) page in Superblocks, selecting the role, and clicking **Edit details**. 8. For **Attribute type** select either **Personal** or **Group**. To learn more about these types, see [Personal vs Group attribute types](#personal-vs-group-attribute-types) 9. Click **Save** Now that you've created the custom attribute, it will show up when you assign users or groups to the Superblocks SCIM app. [Import users from Superblocks](#import-existing-users) to sync to Okta the currently assigned role in Superblocks.

You can also [map Okta attributes to app attributes](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-map-attributes.htm) by configuring mapping rules.
#### Personal vs Group attribute types When assigning roles in Okta via SCIM, you'll need to choose whether to manage roles for each user individually or in groups. Here's the difference: * **Personal**: You'll decide what role to give each user when assigning them to the Superblocks SCIM app. Alternatively, you can create [custom mapping rules](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-map-attributes.htm) to set the role based on other user attributes in Okta. * **Group**: You'll decide what role to associate with each Okta group assigned to the Superblocks SCIM app. You'll then [prioritize your groups](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-prioritize-app-group.htm). When a user is added to one or more of the assigned Okta groups, the role they receive in Superblocks will be based on the group priorities. ## Manage groups with SCIM Optionally, you can set up Okta to manage Superblocks Groups and their members. If this is not configured, new users added through Okta will not be assigned to any custom groups in Superblocks. To sync an Okta group with a Superblocks group: 1. From the Superblocks app in Okta, go to the **Push Groups** tab 2. Click **Push Groups** → **Find groups by name** 3. Enter the name of the **Okta** group you want to sync with Superblocks 4. Okta will try to automatically match the Okta group to a group in Superblocks based on the name. If there is no corresponding group in Superblocks select **Create Group**, otherwise select **Link Group** and choose the Superblocks group you want to sync with. Okta push groups 5. Click **Save**. This will either create a new group in Superblocks or link the group to an existing Okta group. If you choose to **Push group memberships immediately**, users who are members of the group in Okta will be added to the Superblocks group and receive access to any Applications, Workflows, or Scheduled Jobs associated with that Superblocks group. Once group push is configured, when you create a new Superblocks user from Okta, or change which groups they're in within Okta, they'll be automatically added or removed from Superblocks groups that you've synced. Note: Once group push is configured, all user membership changes should be made from Okta. Changing group membership in Superblocks can cause synchronization issues with Okta. # Entra ID SSO setup Source: https://docs.superblocks.com/admin/org-administration/auth/single-sign-on/azure-ad Superblocks single sign-on (SSO) with Entra (formerly Azure AD) lets your team seamlessly authentication and access Superblocks using their Entra credentials. This guide walks trhough how to configure single sign-on for Superblocks. ## Prerequisites To setup SSO for your organization, you'll need: * An Entra tenant * A user account with, at a minimum, [Cloud application administrator](https://learn.microsoft.com/en-us/azure/active-directory/roles/permissions-reference#cloud-application-administrator) access * A Superblocks organization on the **[Enterprise](https://www.superblocks.com/pricing)** plan ## Setup Set up single sign-on for Entra by registering an application in the Entra portal. See Microsoft's [Quickstart: Register an application with the Microsoft identity platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) for full details. ### Register an application 1. Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com/) 2. Navigate to **Identity** → **Applications** → **Enterprise applications** 3. Click **+ New application** 4. Select **+ Create your own application** 5. Name the application Create Entra Application 6. Set **Supported account types** to **Accounts in this organizational directory only** 7. Under **Redirect URI** select **Web** and enter `https://login.superblocks.com/login/callback` 8. Click **Register** ### Setup authentication After your app has been registered, configure authentication for the application. 1. In **App registrations** select your new application 2. Under **Manage**, select **Authentication** 3. Set the **Front-channel logout URL** to `https://app.superblocks.com/logout` 4. Under **Implicit grant and hybrid flows** check the boxes for both **Access tokens** and **ID tokens** 5. **Save** your configuration For customers on Superblocks EU set the logout URL to [https://eu.superblocks.com/logout](https://eu.superblocks.com/logout) Entra Enterprise Application Setup ### Add a client secret Superblocks uses a client secret to authenticate with Entra when requesting user access tokens. To create a client secret for your application: 1. Under **Manage**, select **Certificates & secrets** 2. On the **Client secrets** tab, click **+ New client secret** 3. Enter a description and select an expiration date for your secret 4. Click **Add** 5. Copy the secret **value** The secret value will never be shown again after you leave this page. Be sure to copy and save it to a safe place like your password manager. ### Configure IdP-initiated login (optional) To allow users to log in to Superblocks directly from Entra instead of initiating the login from Superblocks, follow the steps below to update the login URL for the Entra application. 1. Under **Manage**, select **Manifest** 2. Scroll down to the `signInURL` property and set its value to `https://app.superblocks.com?connection={MyCompanyName}-AzureAD` Replace `{MyCompanyName}` with your company's name. Remove all spaces and special characters from the name. If your company name is multiple words, capitalize the first letter of each word. For example, the company River Bank Technologies would become `RiverBankTechnologies` 3. Click **Save** Update signInURL for IdP-initiated login ## Send IdP info to Superblocks Once you've configured your Entra application, send the following information to [support@superblocks.com](mailto:support@superblocks.com)
Client ID The Application (client) ID for your Entra tenant. You can find this value on your app's Overview screen.
Client Secret The secret value you copied when you added a client secret. Note: we recommend using a secure transfer mechanism such as `https://onetimesecret.com` or similar to send the secret.
Entra Tenant Domain Your Entra domain name. You can find this on your Entra tenant overview page in the Microsoft portal.
Other domains The list of domain and domain aliases your employees should be able to use when logging into Superblocks.
# Google SSO setup Source: https://docs.superblocks.com/admin/org-administration/auth/single-sign-on/google Superblocks single sign-on (SSO) with Google Workspace lets your team seamlessly authenticate and access Superblocks using their Google credentials. This guide walks through how to configure single sign-on for Superblocks. ## Prerequisites To setup SSO for your organization, you'll need: * A Google Workspace account * Google Workspace administration access * A Superblocks organization on the **[Enterprise](https://www.superblocks.com/pricing)** plan ## Setup Google Workspace Set up single sign-on for Google by creating either a **SAML** or **OIDC** application. For full details, see Google's guides for how to: * [Create a custom SAML app](https://support.google.com/a/answer/6087519) * [Set up OAuth 2.0 (OIDC)](https://support.google.com/googleapi/answer/6158849) For the fastest setup and seamless integration with the Superblocks Sign-in with Google experience, create an OAuth2.0 app.

If you plan on using SCIM for user provisioning and group management, create a SAML app. Learn more about Managing users and groups with SCIM.
### Create an OAuth app 1. Log in to Google Cloud and go to the [**API Console**](https://console.developers.google.com/) 2. Select a Google Cloud project or create a new one 3. Navigate to the **APIs & services** page from the left side menu 4. On the left, click **Credentials** 5. Click **Create Credentials**, then select **OAuth client ID** 6. Select **Web application** as the **Application type** 7. Configure the following settings for your application
Name Superblocks, or a custom name
Authorized JavaScript origins [https://login.superblocks.com](https://login.superblocks.com)
Authorized redirect URIs [https://login.superblocks.com/login/callback](https://login.superblocks.com/login/callback)
8. Click **Create**. A modal will open with your OAuth client information. Keep this modal open and go to the section below to determine [what info to send to Superblocks](#oauth-application). ### Create a SAML app 1. Log in to Google Workspace and go to the **Admin Console** 2. Navigate to **Apps** → **Web and mobile apps** 3. Click **Add App** → **Add custom SAML app** 4. Provide the general information for the integration and click **Continue** 5. On the **Google Identity Provider details** download the **IDP metadata** file, or copy and save the [info to send to Superblocks](#saml-application) 6. Click **Continue** 7. Enter the following information into the **Service Provider Details**
ACS URL [https://login.superblocks.com/login/callback?connection=\{CompanyName}-SAML](https://login.superblocks.com/login/callback?connection=\{CompanyName}-SAML)
Entity ID urn:auth0:superblocks-prod:\{CompanyName}-SAML
Name ID format EMAIL
Name ID Basic Information > Primary email
Replace with your company's name. Remove all spaces and special characters from the name. If your company name is multiple words, capitalize the first letter of each word.

For example, the company River Bank Technologies would become RiverBankTechnologies.
8. Click **Continue** 9. Click **Add mapping** and configure the following user attributes | Google Directory attributes | App attributes | | --------------------------- | -------------- | | Primary email | email | | First name | givenname | | Last name | surname | 10. Click **Finish** and continue to [send your SAML app info to Superblocks](#saml-application). ## Send IDP info to Superblocks ### OAuth application Send the following information to [support@superblocks.com](mailto:support@superblocks.com)
Client ID The public identifier for your client located on the General tab of your application.
Client Secret The secret value shows in the CLIENT SECRETS section. Note: we recommend using a secure transfer mechanism such as `https://onetimesecret.com` or similar to send the secret.
Google Workspace domain Google Workspace domain name for your organization.
Domains A list of domain and domain aliases your employees should be able to use when logging in to Superblocks.
### SAML application Send the following information to [support@superblocks.com](mailto:support@superblocks.com)
Connection Name The connection name you created above and configured in the ACS URL and Entity ID.
SSO URL The Identity Provider Single Sign-On URL provided when you created the SAML app.
X509 Signing Certificate The certificate downloaded from the Identity Provider details
Domains A list of domain and domain aliases your employees should be able to use when logging into Superblocks.
# Single Sign-On (SSO) overview Source: https://docs.superblocks.com/admin/org-administration/auth/single-sign-on/index Set up Single Sign-On to let your team log in to Superblocks using your organization's identity provider Single sign-on overview SSO lets your team authenticate with Superblocks using the same identity provider (IdP) you use for your other internal and external services. Superblocks supports both SAML 2.0 and OIDC, as well as a large variety of identity providers, including Okta, Entra, Google, OneLogin and more. Use SSO to streamline member login and make it simple for your IT team to manage Superblocks access and keep your data and applications secure. ## Supported identity providers We provide support for the following identity providers: * [Okta](/admin/org-administration/auth/single-sign-on/okta) * [Google Workspace](/admin/org-administration/auth/single-sign-on/google) * [Azure Entra ID](/admin/org-administration/auth/single-sign-on/azure-ad) * OneLogin * PingFederate * ADFS * OpenID Connect * Custom SAML # Okta SSO setup Source: https://docs.superblocks.com/admin/org-administration/auth/single-sign-on/okta Superblocks single sign-on (SSO) with Okta lets your team seamlessly authenticate and access Superblocks using their Okta credentials. This guide walks you through how to configure single sign-on for Superblocks. ## Prerequisites To setup SSO for your organization, you'll need: * An Okta account * A user account with **[App Admin](https://help.okta.com/en-us/content/topics/security/administrators-admin-comparison.htm)** access * A Superblocks organization on the **[Enterprise](https://www.superblocks.com/pricing)** plan ## Set up Okta Set up single sign-on for Okta by creating either a custom **SAML** or **OIDC** application. For full details, see Okta's guides for how to: * [Create SAML app integrations](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_saml.htm) * [Create OIDC app integrations](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_oidc.htm) For the fastest setup, create an OIDC integration.

If you plan on using SCIM for user provisioning and group management, we recommend creating a SAML integration. Learn more about Managing users and groups with SCIM .
### Create an OIDC integration 1. Log in to Okta and go to the **Admin Console** 2. Navigate to **Applications** → **Applications** 3. Click **Create App Integration** 4. Select **OIDC - OpenID Connect** as the **Sign-on method** 5. Select **Web Application** as the **Application type** and click **Next** 6. Configure the following settings for your application
Name Superblocks, or a custom name you want users to see on their application dashboard.
Grant type Implicit (hybrid)
Sign-in redirect URIs [https://login.superblocks.com/login/callback](https://login.superblocks.com/login/callback)
Sign-out redirect URIs [https://app.superblocks.com/logout](https://app.superblocks.com/logout)
Assignments Your desired settings for who can access Superblocks.
7. Click **Save**. You'll be brought to the **General** tab of your new application. Stay on this tab and continue to find out [what info to send to Superblocks](#oidc-application). ### Create a SAML integration 1. Log in to Okta and go to the **Admin Console** 2. Navigate to **Applications** → **Applications** 3. Click **Create App Integration** 4. Select **SAML 2.0** as the **Sign-on method** 5. Provide the general information for the integration and click **Next** 6. Enter the following information into **SAML Settings** → **General**
Single sign-on URL [https://login.superblocks.com/login/callback?connection=](https://login.superblocks.com/login/callback?connection=)\-SAML
Audience URI `urn:auth0:superblocks-prod:-SAML`
Name ID format EmailAddress
Application username Email
Replace `` with your company's name. Remove all spaces and special characters from the name. If your company name is multiple words, capitalize the first letter of each word.
For example, the company River Bank Technologies would become `RiverBankTechnologies`
7. Configure the follow attributes in **SAML Settings** → **Attribute Statements** | Name | Name format | Value | | --------- | ----------- | -------------- | | email | Unspecified | user.email | | givenname | Unspecified | user.firstName | | surname | Unspecified | user.lastName | 8. Click **Next** and fill out the Okta feedback form, then click **Finish**. 9. You'll be brought to the **Sign on** tab of your new application. Click **View Setup Instructions** and continue to the next section to learn [what info to send to Superblocks](#saml-application). ## Send IDP info to Superblocks ### OIDC application Send the following information to [support@superblocks.com](mailto:support@superblocks.com)
Client ID The public identifier for your client located on the General tab of your application.
Client Secret The secret value shows in the CLIENT SECRETS section.

Note: we recommend using a secure transfer mechanism such as [https://onetimesecret.com](https://onetimesecret.com) or similar to send the secret.
Okta domain Your company's Okta domain. You can find this by clicking your username in the upper-right corner of the Admin Console. Learn more about how to Find your Okta domain.
Domains A list of domain and domain aliases your employees should be able to use when logging into Superblocks.
Google Sign-in If you use Google Workspace, let us know if you want employees to also be able to log in with their Google credentials, or if they should be forced to log in using Okta.
### SAML application Send the following information to [support@superblocks.com](mailto:support@superblocks.com)
Sign In URL The Identity Provider Single Sign-On URL in the Okta setup instructions.
X509 Signing Certificate The certificate downloaded from the setup instructions.
Metadata URL (optional) Optionally, send us the Metadata URL shown on the Sign on tab of your application.
Domains A list of domain and domain aliases your employees should be able to use when logging into Superblocks.
Google Sign-in If you use Google Workspace, let us know if you want employees to also be able to log in with their Google credentials, or if they should be forced to log in using Okta.
# About user groups Source: https://docs.superblocks.com/admin/org-administration/groups Organize users into groups to streamline the management of permissions and access across your organization With user groups, you can easily: * Grant users different levels of access to Superblocks by assigning organization roles to groups. * Manage resource access at scale by assigning resource-level permissions to groups. * Customize your app's user experience and security by creating in-app authorization checks on pages, APIs, and components. # Managing group permissions Source: https://docs.superblocks.com/admin/org-administration/groups/managing-group-permissions **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `groups:manage` permission
To grant a group of users permissions in Superblocks, you can either assign them an [organization role](/admin/org-administration/org-roles) that defines the Superblocks feature/admin permissions they receive, or a [resource role](/admin/org-administration/resource-roles) that grant them access to an Application, Integration, Workflow, or Scheduled Job. To learn more about the types of roles and access they grant, see [Permissions in Superblocks](/admin/org-administration/rbac) ## Assigning org role to a group To assign an organization role to a group: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Groups**](https://app.superblocks.com/groups) 3. Find the name of the group 4. Click into the **Role** selector and choose the role you want to assign to the group Assign custom role to user group ## Removing org role from a group To remove an organization role from a group: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Groups**](https://app.superblocks.com/groups) 3. Find the name of the group 4. Click the × icon next to the role name ## Managing a group's access to a resource Groups can be granted access to individual resources as well by assigning the group a [resource role](/admin/org-administration/resource-roles). To share a resource with a group: 1. Navigate to the resource (Application, Workflow, Integration, etc) you want to grant access to 2. Click into the editor or configuration page for that resource 3. Find and click on the **Share** button in the upper right-hand corner of the page 4. In the dialog box that appears, search for the group you want to share the resource with 5. Select the **Resource role** you want to assign to the group 6. Click **Share** UI showing user assigning QA permissions to Product Teams for an Application ## How group roles interact with individual member roles Roles and permissions are additive. If a person is given different levels of access through different avenues, such as a group membership and their individually assigned role, the user has the **sum of all access grants**. For example, let's say an organization owner assigns a user the [built-in role](/admin/org-administration/org-roles#built-in-organization-roles) of End-User. They're then added to a group that has a [custom role](/admin/org-administration/org-roles/custom-roles) with all Integrations permission. This member will have management access to all Integrations, but won't be able to create Apps, Workflows, or Jobs, because of the permissions granted through the combination of their individually assigned role and the custom role. If a member belongs to multiple groups, the members permissions will include the permissions associated with the role individually assigned to them, plus the permissions granted to each of their groups. # Managing user groups Source: https://docs.superblocks.com/admin/org-administration/groups/managing-groups **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `groups:manage` or `groups.members:manage` permission
## Overview User groups enable large organizations to efficiently manage members and their access in Superblocks. By organizing users into groups, new tools can be quickly shared with different parts of the organization. [Custom roles](/admin/org-administration/org-roles/custom-roles) can also be assigned to grant group members access beyond the permissions granted to users through their individually assigned role. Learn more about [Managing group permissions](/admin/org-administration/groups/managing-group-permissions) Superblocks also supports syncing groups and group memberships with SCIM. Learn more about managing groups with [SCIM](/admin/org-administration/auth/scim). ## Creating a group To create a new user group: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Groups**](https://app.superblocks.com/groups) 3. Click **+ Add group** 4. Create a name for your group 5. Select the members you want to add to the group 6. Click **Create** Create a new user group Once you've created a group you can assign a [custom organization roles](/admin/org-administration/org-roles/custom-roles) to the group to grant members additional permissions. Learn more about in [Managing group permissions](/admin/org-administration/groups/managing-group-permissions) ## Add members to a group To add members to a group: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Groups**](https://app.superblocks.com/groups) 3. Click on the name of a group to navigate to that group's page 4. On the **Members** tab click **+ Add member** 5. Select the members to add to the team 6. Click **Add members** ## Remove members from a group To remove a member from a group: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Groups**](https://app.superblocks.com/groups) 3. Click on the name of a group to navigate to that group's page 4. Find the member in the list of team members 5. Select the dropdown menu (⋯) at the right of the row of the member you want to remove 6. Select **Remove from group** 7. Click **Remove** in the confirmation dialog ## Deleting a group You can delete groups from the Groups page. To delete a group: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Groups**](https://app.superblocks.com/groups) 3. Select the dropdown menu (⋯) at the right of the row of the group you want to delete 4. Click **Remove group** 5. Click **Remove** in the confirmation dialog # Organization knowledge Source: https://docs.superblocks.com/admin/org-administration/knowledge Define org-wide standards and conventions that Clark follows by default Organization knowledge applies to every Clark conversation across your entire org. Use it to encode information that all builders should benefit from, so Clark builds consistently with your team's standards — things like design systems, coding conventions, domain terminology, and team-wide patterns. ## Adding org knowledge Navigate to the **Knowledge** page and chat with Clark to describe what you want it to remember. Clark will create the right knowledge entry at the right scope for you, then present it for your review before saving. We recommend using Clark to write entries because it optimizes them for LLM retrieval — producing focused, well-structured instructions that Clark can look up effectively at build time. Clark Knowledge page For example, you might tell Clark: * "Our design system uses primary (#0099FF), secondary (#6B7280), and danger (#EF4444). Never hardcode other colors for interactive elements." * "All API error responses must be caught and displayed with a toast notification. Never silently swallow errors." * "When referring to customers, use 'account' not 'client' or 'customer'. Our data model uses `account_id` as the primary identifier." Clark will draft the entry, set the scope to **Organization**, and present it for your review before saving. Clark creating an org knowledge entry You can also ask Clark to **explore your existing knowledge**, refine entries, or identify duplicates — for example, "Review my org knowledge and flag any entries that overlap or contradict each other." ## Permissions Creating, updating, and deleting org knowledge requires Owner or Admin permissions. Once entries are saved, they are available to all builders in the org — you cannot restrict who benefits from org knowledge, because it's designed to apply everywhere. Organization knowledge permissions Individual entries can be enabled or disabled from the Knowledge page. Enabling too many knowledge entries at once can reduce Clark's effectiveness. Keep entries focused and disable any that aren't actively needed. ## Related Organization knowledge is part of Clark's broader [Knowledge](/building-with-clark/knowledge) system. You can also define knowledge at the [integration](/integrations/knowledge), [user](/building-with-clark/knowledge/user-knowledge), and [app](/building-with-clark/knowledge/app-knowledge) levels. # About organization members Source: https://docs.superblocks.com/admin/org-administration/members Everything you build in Superblocks is built in and belongs to a Superblocks organization. Organizations are the central place where you'll collaborate with your team when building tools, and where your teammates will access and use the tools you've built. To collaborate with others and share non-public tools, you'll need to add others to your organization as members. Organization members are people who work at your organization or anyone who needs access your organization's internal tools, such as contractors, part-time employees, etc. You can view the members of your organization on the [Users](https://app.superblocks.com/users) page on Superblocks. Learn more about inviting and managing your organization members in this section. # Permanently delete a user from Superblocks Source: https://docs.superblocks.com/admin/org-administration/members/delete-user The **Owner** of a Superblocks organization can request that users be permanently deleted from Superblocks. ## Background * The **Owner** of a Superblocks organization controls all data for their organization. This includes anything built by members of their org and member profiles. * When members leave a Superblocks org, they may have the right to request their profile be deleted. As the data controller, the **Owner** is responsible for determining whether information requires deletion. * Users can only be deleted once a member's account is [deactivated](/admin/org-administration/members/remove-user). Once the user's account is deleted, it can't be recovered. ## What information is deleted? Deleting a user from Superblocks will remove the following user information: * Display name * Email address * Profile picture * Custom user attributes Content that isn't considered profile information won't be removed from Superblocks. This includes: * Resources the user has created (Applications, Integrations, etc) * Commits created by the user * Deployments triggered by the user * Audit log records associated with the user's activity Commits, deployments, and audit log records will show as having been done by "Deleted user" ## Submit a request to delete a user If you are the **Owner** of your Superblocks org, you can request that users be deleted by sending the following information to [support@superblocks.com](mailto:support@superblocks.com): * Your organization name * The **email address** of all of the users you want to delete Please make sure all users are [deactivated](/admin/org-administration/members/remove-user) before filing the request. # Manage organization members Source: https://docs.superblocks.com/admin/org-administration/members/invite-users Invite users to become members of your Superblocks organization **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `org.users:manage` permission
Superblocks also supports user management with OAuth and SAML based Single Sign on, and SCIM. Learn more about [enabling single sign-on](/admin/org-administration/auth/single-sign-on) and [SCIM](/admin/org-administration/auth/scim) ## About invitations To add someone to your Superblocks organization, you'll need to [invite them to join](#invite-users-to-join) the org. When you invite someone to your Superblocks organization, they'll receive an email with an invitation link. To join the organization, the invitee just needs to click the invitation link in the email. People will only become full members of your organization once they've accepted their invitation. You can implement SCIM to add, manage, and remove organization members' access to Superblocks through an identity provider (IdP). Users added to organization via SCIM do not receive invitation emails. Learn more about [SCIM](/admin/org-administration/auth/scim). ## Member emails When inviting users to your organization, you'll need to provide an email address. Superblocks users can only be a member of a single organization at a time. If someone has already been invited or joined a different Superblocks org, you won't be able to invite them using the same email address. To keep things simple and secure, we recommend inviting users with email addresses that are tied to your organization's domain. It's best to avoid personal email addresses or emails from outside your organization. If you try to invite a user with an email that's already in another Superblocks org, you'll get an error. If this user need access to multiple organizations, it's recommended to use different email addresses, or email aliases. ## Invite users to join 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Users**](https://app.superblocks.com/users) 3. Click **+ Invite user** 4. Enter one or more email addresses. If you are inviting multiple members, separate emails with a comma. 5. Choose an initial [built-in or custom role](/admin/org-administration/org-roles) from the **Organization role** dropdown 6. (Optional) Select groups to add these members to 7. Click **Invite users**
Invite users to Superblocks
1. The invited people will receive emails inviting them to the organization. They will need to accept the invitation before becoming a member of the organization. You can edit or cancel an invitation any time before the user accepts. ## Cancel an invitation Invitations never expire. If you no longer want a user to join your organization, you can cancel their invitation. To cancel an invitation: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Users**](https://app.superblocks.com/users) 3. Find the invited user by entering their name or email into the search box, or filter the list to invited users Filter user list to invited users 1. Next to the user, select the dropdown menu (⋯), then click **Remove invite** Cancel user invite 1. To confirm, click **Remove** # Removing a member from your organization Source: https://docs.superblocks.com/admin/org-administration/members/remove-user Remove members from your organization by deactivating their account **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `org.users:manage` permission
Superblocks also supports user management with OAuth, SAML, and SCIM. Learn more about [enabling single sign-on](/admin/org-administration/auth/single-sign-on) and [SCIM](/admin/org-administration/auth/scim). ## Deactivate a user's account 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Users**](https://app.superblocks.com/users) 3. Find the user by entering their name or email into the search box 4. Next to the user, select the dropdown menu (⋯), then click **Deactivate** 5. To confirm, click **Deactivate** Removing a member from your organization has the following consequences: * They are removed from any user groups they were added to * The roles assigned to them for any resource are removed * Their personal access token is deactivated * They're signed out and will not be able to log back in They aren't notified that their account was deactivated, nor are any resources they've created deleted. If you change your mind, you can reach out to our [support team](/enterprise/support/help) to reactivate the account. Deactivating a member's account does not delete profile information, like the user's name and email. The user will still appear in the Users list in case you want to reactivate them at a future point. **Owners** can request to [permanently delete user accounts](/admin/org-administration/members/delete-user). # About organization roles Source: https://docs.superblocks.com/admin/org-administration/org-roles Use organization roles to determine the actions a user can perform within the Superblocks platform Roles are used to define a set of permissions that you can assign to individuals or groups. Organization-level roles control the Superblocks features members can access, the administrative actions they can perform, and the level of access users have to all current and future resources created in the org. Note, organization-level roles differ from resource-level roles that give users access to specific Applications, Integrations, Workflows, etc. For more information, see [About resource roles](/admin/org-administration/resource-roles). ## Built-in organization roles Each Superblocks organization, by default comes out of the box with the following built-in roles. These roles are non-editable and are based on common patterns of permissions organizations usually need. * **Owner**: Each Superblocks organization has a primary Owner. This person is considered the controller of all org data. Only they can request to [delete users](/admin/org-administration/members/delete-user), delete the organization, or request plan and billing changes. * **Admin**: Admins help manage their organization, including members, groups, and settings. Admins can also access all of the organization's resources to help manage access to these resources. * **Developer**: The default non-administrative role is Developer. Developers build and maintain your company's tooling. They can't change org settings, but otherwise have read-only access to most of your org's settings. * **End-User**: End-Users have the lowest level of access in Superblocks. They have read-only access to the platform, can't view most org settings, and can only access resources they've been given access to. For more granular control of permissions, you can create custom organization roles. For more information, see [Custom organization roles](/admin/org-administration/org-roles/custom-roles) For more information using roles, see [Using organization roles](/admin/org-administration/org-roles/using-org-roles) ## Permissions for built-in organization roles The built-in organization roles have the following permissions. For a full list of permissions that can be assigned with organization roles, see the [permissions reference](/admin/org-administration/org-roles/permissions) # About custom organization roles Source: https://docs.superblocks.com/admin/org-administration/org-roles/custom-roles **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `roles:manage` permission
You can granularly control user permissions with custom organization roles. Organization roles control the Superblocks features members can access, the administrative actions they can perform, and the level of access users have to all current and future resources created in the org. For example, you can use custom roles to grant a set of users permission to manage self-hosting the Superblocks data plane, without granting permission to invite and manage org members. Or let users create Apps, Workflows, and Jobs without granting permission to add Integrations. Each custom roles includes a set of permissions. Permissions either let users: * Do certain types of development. See [development permissions](/admin/org-administration/org-roles/permissions#development) * Gain access to **all current and future resources** in the org. See [resource access permissions](/admin/org-administration/org-roles/permissions#resource-level-access) * Manage certain org settings and features. See [governance permissions](/admin/org-administration/org-roles/permissions#governance) This guide walks through how to create and manage custom organization roles. To learn more about assigning roles see [Using organization roles](/admin/org-administration/org-roles/using-org-roles) ## Creating a custom role Organizations can create up to 10 custom organization roles. To create an organization role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/organization-roles) 3. On the **Organization roles** tab, click **+ Add role** 4. Type a name and description for the custom role 5. Click **Create** 6. Add permissions to your custom role by selecting permissions in the permission table. For a full reference to assignable permissions see the [Permissions reference](/admin/org-administration/org-roles/permissions) 7. Once you've selected all the permissions you want assigned to the role, click **Save** ## Editing a custom role's details To edit the name or description of a custom role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/organization-roles) 3. Next to the role you want to edit, select the dropdown menu (⋯), then click **Edit details** 4. Change the role as required, then click **Save** ## Editing a role's permissions To edit the permissions associated with a custom role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/organization-roles) 3. Check/uncheck the boxes associated with permissions you want to add/remove from the role. Alternatively, if you want to grant all permissions associated with a type of Superblocks resource, check the box at the top of the resource group. 4. Once you've made all your permission selections, click the **Save** button at the bottom of the page Manage permissions of custom organization role For a full reference of permissions and the access they grant, see [Permissions reference](/admin/org-administration/org-roles/permissions) ## Deleting a custom role 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/organization-roles) 3. Next to the role you want to delete, select the dropdown menu (⋯), then click **Delete** 4. In the confirmation dialog, choose a new role to assign to users who are currently assigned the role being deleted 5. Click **Reassign & delete** # Organization role permission reference Source: https://docs.superblocks.com/admin/org-administration/org-roles/permissions Full reference to permissions assignable to users with organization roles Organization-level roles control the Superblocks features members can access, the administrative actions they can perform, and the level of access users have to all current and future resources created in the org. ## Governance ## Development ## Resource-level access Custom organization roles can also be used to grant the following access to **all current and future resources** in the organization. # Using organization roles Source: https://docs.superblocks.com/admin/org-administration/org-roles/using-org-roles **Who can use this feature?**
Organization **Owners**, **Admins**, and users with `org.users:manage` or `groups:manage` permission
Each member of a Superblocks organization has an organization role. These roles control the Superblocks features that members can access, the administrative actions they can perform, and the level of access they have to all current and future resources created in the org. Users can be assigned a [built-in role](/admin/org-administration/org-roles#builtin-organization-roles), or you can create up to 10 custom roles. For more information, see [About custom organization roles](/admin/org-administration/org-roles/custom-roles) This guide walks through how to manage the organization roles assigned to individuals and groups in Superblocks. Superblocks also supports managing roles with SCIM. Learn more about [SCIM](/admin/org-administration/auth/scim) ## Viewing role permissions To view the permissions associated with an organization role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/organization-roles) 3. Expand/collapse resources in the table to view the permissions associated with each role Organization role permissions Permissions listed grant access to manage the organization and permissions to **all current and future resources** in the organization. Learn more about [organization role permissions](/admin/org-administration/org-roles/permissions) ## Setting default role Each member of your organization must have an organization role. When users are [invited](/admin/org-administration/members/invite-users) to your org, you must select the role that will be assigned. If your organization lets users join your team based on their email domain, they will be assigned the **default role** set for your organization. To update your org's default role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/settings) and go to the **Settings** tab 3. Update the **New user default role** Set role to assign to new users Now, when users join your team, they will automatically be assigned this role. ## Assign organization roles ### Assign to individual user To change the role of an individual member: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Users**](https://app.superblocks.com/users) 3. Find the user by entering their name or email into the search bar 4. Click into the **Role** selector and choose the new role you want to assign ### Assign to multiple users To update the role assigned to multiple organization members: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Users**](https://app.superblocks.com/users) 3. Select the checkbox to the left of the members' name to select that member 4. Select all members that you want to update. Alternatively, if you wish to select all the members, click the checkbox next to the Name column in the table. 5. Next to the Invite user button, another button will appear for bulk **Actions** 6. Click the **Actions** button and then select **Change user roles** 7. Select a new role for all of the selected users and click **Save** ### Assign roles to groups Assigning roles to groups is optional but can be beneficial for efficiently managing permissions across users who share similar responsibilities. For full details on how group roles interact with user roles and how to manage group roles, see [Manage group permissions](/admin/org-administration/groups/managing-group-permissions) # Organization administration overview Source: https://docs.superblocks.com/admin/org-administration/overview Govern, manage, and scale access to all of your tools with Superblocks. * Securely manage user identities for developers and end-users with Single Sign-on * Simply manage access to your data and applications with permissions * Scale up access management at any size with Groups and SCIM * Customize application UIs and manage in-app permissions in code ## Start here ## All administration docs # Superblocks RBAC Source: https://docs.superblocks.com/admin/org-administration/rbac Use role-based access control (RBAC) to control the level of access users have to your organization and resources in Superblocks ## About permissions To perform any action in Superblocks, such as creating an Application, connecting to a Repository, or adding a user to a group, a person must have sufficient access to do so. This access is controlled by permissions where permissions are the ability to perform a specific action. For example, the ability to build with an integration is a permission. Users get permissions based on the roles they are assigned, or based on the roles assigned to groups they are a member of. ## Types of roles There are two types of roles that can be assigned to users and groups in Superblocks: **Organization roles:** Organization roles control the Superblocks features members can access and the permissions a user has to help administer the org. They can also be used to grant users access to all current and future Apps, Integrations, Workflows, and Scheduled Jobs that belong to the org. **Resource roles:** Resource roles grant a user permissions for a specific resource, for example, a specific Application, Integration, etc. ## Further reading For more info about roles, the permission they grant, and how to assign them, see: # About resource roles Source: https://docs.superblocks.com/admin/org-administration/resource-roles Use resource roles to define permissions on specific Applications, Integrations, Workflows, and Schedued Jobs You can give organization members and groups different levels of access to specific Applications, Integrations, Workflows, and Scheduled Jobs. Just choose the role that best fits each person or groups's function without giving them more access than they need. Each permissionable resource comes with a set up [built-in roles](#resources-with-roles). You can also create custom resource roles to customize levels of access. For more information, see [Custom resource roles](/admin/org-administration/resource-roles/custom-roles) Organization admins can also set base permissions that all members will receive for newly created resources. For more information, see [Setting base permissions for resources](/admin/org-administration/resource-roles/base-permissions) ## Resources with roles Not all resources support resource roles. Resources that support roles are those which let a user share an instance of a resource with users and groups. For example, applications support resource roles because users can independently share **Application A** and **Application B** with different sets of users. Data plane instances don't support resource roles since they are set up at the platform level and not individually shared with users. The following resources currently support resource-role assignments: * [Applications](#applications) * [Integrations](#integrations) * [Scheduled Jobs](#scheduled-jobs) * [Workflows](#workflows) ## Permissions for roles Each resource has a unique set of built-in roles based on the common patterns of permissions that organizations generally use. The following built-in roles are available in every organization for the following resources: ## Further reading # Resource base permissions Source: https://docs.superblocks.com/admin/org-administration/resource-roles/base-permissions Manage the resource access users receive on newly created resources with base permissions **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `roles:manage` permission
## About base permissions The base permissions of a resource define the set of permissions all members of your organization receive on newly created resources. For example, if the base permission for Integrations is set to Developer, when a new Integration is created, all members of the organization will be granted the `integration:build` permission for that Integration. ## Base permission defaults By default, members of an organization get the following permissions to the organization's resources based on the resource type: | Resource | Base permission | | ------------------------------------------------------------------------- | --------------- | | [Applications](/admin/org-administration/resource-roles#applications) | End-User | | [Integrations](/admin/org-administration/resource-roles#integrations) | No access | | [Scheduled Jobs](/admin/org-administration/resource-roles#scheduled-jobs) | No access | | [Workflows](/admin/org-administration/resource-roles#workflows) | No access | ## Setting base permissions To update the base permissions for a resource type: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/settings) 3. Click on the **Settings** tab 4. Select the base permission dropdown and choose the permissions level you want to set * Changes to base permissions only affect newly created resources. Permissions for existing resources will not be affected * Resource Admins can grant everyone within the organization different access than the base permission by changing the resource's permissions # Manage creator roles Source: https://docs.superblocks.com/admin/org-administration/resource-roles/creator-roles Change the role assigned to resource creators to limit the permissions they receive on that resource **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `roles:manage` permission
## About the creator role The creator role defines the [resource role](/admin/org-administration/resource-roles) that will be assigned to a user when they create a resource of that type. By default, creators are assigned the **Admin** role for the resource they've created. The built-in Admin roles give users all permissions to the resource they've created. To reduce the set of permissions granted to resource creators, [change the creator role](#changing-the-creator-role) for the resource type. For example, I may want to assign the [Developer](/admin/org-administration/resource-roles#applications) role to application creators so that users cannot share access to applications they create or make them public. ## Changing the creator role To update the creator role for a resource type: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/settings) 3. Click on the **Settings** tab 4. Select the creator role dropdown for the desired resource type and choose the role you want assigned when a user creates a resource Changing the creator role only affects newly created resources. Users who have created resources prior to the change will still have the built-in **Admin** role to that resource. # About custom resource roles Source: https://docs.superblocks.com/admin/org-administration/resource-roles/custom-roles Customize permissions granted on an individual resource with custom resource roles **Who can use this feature?**
Organization **Owners**, **Admins**, and other users with the `roles:manage` permission
Custom resource roles let you gain more control over the permissions users have to manage individual Applications, Integrations, Workflows, and Scheduled Jobs. For example, you can create custom roles like:
| Custom role | Description | Resource | Permissions | | ----------- | ---------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------ | | QA | Lets the QA team review application changes using commit previews, but doesn't give them access to the live app. | Application | `apps:preview` | | Maintainer | Grants permissions to edit an integration's credentials while not letting them delete or share the integration | Integration | `integrations:update`
`integrations:build` | | Contributor | Can make updates to assigned Workflows, but can't deploy their changes. | Workflow | `workflows:update` |
## Creating a custom role To create a custom resource role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/resource-roles) 3. Click on the **Resource roles** tab 4. Locate the resource you want to create a custom role for 5. On the resource roles table, click **+** icon Create custom resource role 6. Type a name and description for the custom role 7. Click **Create** 8. Add permissions to your custom role by selecting the permissions in the permission table 9. Once you've selected all the permissions you want assigned to the role, click **Save** After you create a custom role: * Anyone with the `*:share` permission of a resource can assign the role to users or groups. See [Managing access to resources](/admin/org-administration/resource-roles/manage-access) * You can make this role what everyone receives when new resources are created. See [Resource base permissions](/admin/org-administration/resource-roles/base-permissions) * You can make the role the one assigned to resource creators. See [Manage creator roles](/admin/org-administration/resource-roles/creator-roles) ## Editing a custom role's details To edit the name or description of a custom role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/resource-roles) 3. Click on the **Resource roles** tab 4. Next to the role you want to edit, select the dropdown menu (⋯), then click **Edit details** 5. Change the role as required, then click **Save** ## Editing a role's permissions To edit the permissions associated with a custom role: 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/resource-roles) 3. Click on the **Resource roles** tab 4. Locate the role you want to edit 5. Check/uncheck the boxes associated with permissions you want to add/remove from the role 6. Once you've made all your permission selections, click the **Save** button at the bottom of the page ## Deleting a custom role 1. Click your avatar in the upper-left corner of the home page and click **Organization Settings** 2. Click [**Roles & Permissions**](https://app.superblocks.com/roles-and-permissions/resource-roles) 3. Click on the **Resource roles** tab 4. Next to the role you want to delete, select the dropdown menu (⋯), then click **Delete** 5. In the confirmation dialog, choose a new role to assigned to users that currently are assigned the role being deleted, or select **Remove access** 6. Click **Reassign & delete** ## Precedence for different levels of access Role and permissions are additive. If a person is given different levels of access through different avenues the user will have the sum of all access grants. For example, if the organization Owner assigns a user the [End-user organization role](/admin/org-administration/org-roles#builtin-organization-roles), and then an app admin gives the user the [Developer](/admin/org-administration/resource-roles#applications) role on their Application, the user will be able to edit the application shard with them even though they cannot create their own Applications. # Manage access to resources Source: https://docs.superblocks.com/admin/org-administration/resource-roles/manage-access Manage individual, group, and app access to individual org resources **Who can use this feature?**
Organization **Owners**, **Admins**, and others with the `*:share` access to a resource
## Who can manage access Users with the `share` permission to a resource can grant others access to that resource. This includes users with both `share` permission to an individual resource, as well as users with an organization role granting them `share` permission to all resources. For example, a user with the [Admin](/admin/org-administration/resource-roles#applications) role on the **Customer 360** application is able to manage others' access to that application. Similarly, a user with the `integrations:share` permission granted to them through an [organization role](/admin/org-administration/org-roles) can manage access to all Integrations. ## Granting users access to resources Resources in Superblocks (Apps, Integrations) can be shared with specific users or groups. When you share the resource, you can select the resource role to grant to the user or group. This role dictates the permissions the user has over the resources. To grant access to an individual resource: 1. Navigate to the resource (Application, Integration) you want to grant access to 2. Click into the editor or configuration page for that resource 3. Find and click on the **Share** button in the upper right-hand corner of the page 4. In the dialog box that appears, search for the individual or group you want to share the resource with 5. Select the **Resource role** you want to assign 6. Click **Share** Grant group access to an Application ## Granting specific apps access to integrations In addition to users and groups, integrations can be shared with specific **apps**. When an integration is restricted to one or more apps, users can only build with this integration from within the specific apps. An integration can be shared across all applications, or restricted to specific applications. * **All apps**: The integration is available across the organization to users who have access to it. This is the default for new and existing integrations. * **Specific apps**: The integration is only available to the apps you select. To control which apps can use an integration: 1. Navigate to the [**Integrations**](https://app.superblocks.com/integrations) page and select the integration 2. Click the **Share** button 3. In the **App availability** section, select **Specific apps** and choose the apps to grant access, or select **All apps** to make it available across the organization 4. Click **Share** to save your changes ### How app and user-level integration access combine when building App availability and a builder's own integration permission are checked independently. * App availability determines which integrations are available within an app. * A builder's integration permission determines which of those integrations he or she can build with. Within a given app, a user can only build with an integration when **both** of the following are true: * The integration is available to that app (either **All apps** or that **specific app**) * The builder has the integration's `build` permission, granted directly or through a group. This means: * Sharing an integration with an app does not give that app's builders permission to build with that integration * A builder's integration permission does not let them use the integration in an app the integration has not been shared with If an integration is already in use within an app and that app's access is removed, existing APIs using this integration will continue to execute. However, builders will not be able to build new APIs with that integration. ### Integration access in published apps (for end-users) A user does not need access to a specific integration in order to use the integration as an end-user of an application. This is intentional; the resource permissions for integrations only restrict who can build with the integration (and in which apps). Once the app is published, users can access any features in the app that are shared with them according to their [App-level RBAC](/building-with-clark/rbac). ## Auditing access changes All changes to resource permissions, including granting or revoking user, group, and app access, are recorded in [Audit logs](/admin/audit-logs). Use audit logs to review who changed access to a resource and when. To view changes to integration access, filter by **Resource: Integration**. ## Granting access to all resources Resource roles give a user access to specific resources. Organization roles differ from resource roles in that they can grant access to **all current and future resources** of a type. To learn more, see [About organization roles](/admin/org-administration/org-roles) ## Change the level of access granted Once a user or group has access to a resource, you can change the level of access they've been granted. To change the access level: 1. Navigate to the resource (Application, Workflow, Integration, etc) you want to grant access to 2. Click into the editor or configuration page for that resource 3. Find and click on the **Share** button in the upper right-hand corner of the page 4. Find the user or group you want to update 5. Select the role dropdown and select the new role you want to set ## Removing access to a resource To remove an individual or group's access to a resource: 1. Navigate to the resource (Application, Workflow, Integration, etc) you want to grant access to 2. Click into the editor or configuration page for that resource 3. Find and click on the **Share** button in the upper right-hand corner of the page 4. Find the user or group you want to remove access from 5. Select the role dropdown and select **Remove** 6. In the confirmation dialog, click **Confirm** Remove access to individual resource # Plan & Usage Source: https://docs.superblocks.com/admin/plan-and-usage Walk through the Plan & Usage page: commitment bar, charts, checkpoint-level GAU spend, and deployed-app charges **Plan & Usage** helps admins understand the ROI of Superblocks at a granular level: which builders and apps create the most value, what it costs to deliver a specific Clark outcome, and how published apps are used against your dollar commit. Open **Organization Settings → Plan & Usage** (admins with billing access). Concepts (GAUs, dollar commit, deployed apps) are on [Billing overview](/admin/billing-overview). Limits and alerts are on [Spend management](/admin/spend-management). This is the experience for customers with a dollar commit with Superblocks. If your organization has a special contract, usage is shown in GAUs instead of dollars in the commitment summary, the usage chart, the usage table (including checkpoint rows), and the deployed applications view. Plan & Usage overview ## Commitment and plan summary At the top of the page, the plan summary shows your contract period and how consumption tracks against your dollar commit. The **commitment / usage bar** summarizes Clark (GAU) and deployed-app usage for the current commit cycle, so you can see how the value you are getting maps to your committed spend. Commitment and usage bar ## Filters, date range, and chart Use the filter bar to focus the chart and tables on the work that matters: * **Date range** (for example Current Month, Contract Period, or previous-month presets) * **User** and **App** filters * **Export** for CSV download of the current usage view Daily usage is aggregated in UTC. The chart shows how usage and value break down over time. You can filter by SKU (**All**, **GAUs**, **Deployed apps**), group (**Total**, **By user**, **By app**), and choose **Daily** or **Monthly** granularity. Usage chart ## Usage table and group by Select the **Shared GAUs** (or equivalent shared spend) resource tile to open the usage table. **Group by** lets you nest rows by **User**, **App**, and **Day** (any combination, reorderable). Use this to see which people, apps, and days deliver the highest-ROI work. Usage breakdown grouped by User, App, and Day ### Checkpoint-level rollup GAU usage rolls up to the relevant **Clark checkpoint** (an accepted set of AI changes), not to each individual prompt. Expand a group to see checkpoint rows with: * Checkpoint label (or a fallback such as "User accepted AI changes") * Date and time * Cost (dollars on dollar-commit) * Billing type when shown (**Committed** or **Overage**) That is how you connect spend to a concrete outcome: what it took to ship a specific change with Clark. Usage that is not tied to an accepted checkpoint (for example work that was never accepted, or usage recorded before checkpoint tracking) can appear under a **No checkpoint** aggregate within the group. Group totals still include that usage. ## Deployed applications Select the **Deployed Apps** resource tile to open the deployed applications statement. Each row is an app for a billed month and can include: * App name and creator * **Months billed** (current month may be marked as of today) * **Billing type**, including **Pending** for a deployed app that will be charged when the month closes * Views (when available) * Cost Use this view to see which published apps are in production, how they are used, and how that usage maps to your commit, including charges that are still pending for the current month. ## Related * [Billing overview](/admin/billing-overview) — GAUs, dollar commit, and deployed-app concepts * [Spend management](/admin/spend-management) — limits, alerts, and refills controls * [Self-serve plans](/admin/self-serve-plan) — Teams packs and GAU refills # Policy Agents Source: https://docs.superblocks.com/admin/policy-agents/index Create AI-powered agents that review applications against your organization's specific policies and standards **Policy Agents** are AI-powered reviewers that admins configure to enforce organization-specific policies. Each agent has its own instructions, a dedicated context window, and access to your organization's [Knowledge](/building-with-clark/knowledge/index). Knowledge tells Clark what to do while it writes code; Policy Agents verify that the output meets your standards before it ships. They cover the rules only your organization can define: compliance requirements, data handling policies, architecture and design system standards, code quality, and performance. For security, Superblocks ships built-in [Code Security](/admin/code-security/index) checks that need no policy authoring. Both appear side by side in the publish readiness checklist. ## How it works A Policy Agent is an AI reviewer that runs against your application at publish time: 1. **Admin creates the agent** with a name, instructions, mode, and scope 2. **Builder publishes**: the agent evaluates a frozen snapshot of the application 3. **Agent produces findings**: structured results with evidence, locations, and severity 4. **Builder sees results** in the publish readiness checklist with clear next actions Multiple agents run in parallel. Each appears as a separate item in publish readiness, so builders know exactly which policy passed and which needs attention. ## Creating an agent Admins configure each Policy Agent with: | Setting | Description | | ---------------- | --------------------------------------------------------------------------------- | | **Name** | Display name shown in publish readiness (e.g., "PHI Storage Agent") | | **Instructions** | The policy the agent enforces, written in natural language, as detailed as needed | | **Mode** | **Blocking** (prevents publish until resolved) or **Advisory** (warns but allows) | | **Scope** | Which applications the agent applies to: all apps, or a specific subset | ### Writing effective instructions Agent instructions work best when they are specific, concrete, and reference your organization's actual standards. You can reference your organization's [Knowledge](/building-with-clark/knowledge/index) to give agents access to existing policies and documentation. Examples of effective instructions: * "Check that any application storing or transmitting patient health information (PHI) only writes to integrations on the approved PHI storage list. Flag any write operation to an unapproved destination as a blocking finding." * "Verify that all API endpoints that perform write operations include role-based access control checks. Any endpoint that modifies data without verifying the caller's permissions should be flagged." * "Confirm that no application stores secrets or credentials in environment variables, local storage, or hardcoded values. All secrets must be referenced through Superblocks integrations." ## What the agent can access Policy Agents have read-only access to the application being reviewed: * Application source files and component structure * Application metadata and configuration * Integration references and connection details * Findings from built-in [static analysis](/admin/code-security/static-analysis) (so agents can build on deterministic results) Agents cannot modify the application. They evaluate and report, and Clark handles remediation. ## Relationship to Clark Policy Agents and Clark serve distinct roles: | | Policy Agent | Clark | | ---------- | ----------------------------------- | ----------------------------------------- | | **Role** | Reviewer that evaluates and reports | Fixer that remediates findings | | **When** | Runs at publish time | Runs when builder clicks "Fix with Clark" | | **Access** | Read-only app state | Read-write app state | | **Output** | Structured findings | Code changes | When a Policy Agent blocks publish, the builder can ask Clark to fix eligible findings. Clark modifies the app, and then a fresh agent run verifies the fix resolved the issue. The agent never resolves its own findings. Independent verification is always required. ## Example use cases ### PHI storage compliance > "Flag any application that writes patient identifiers, diagnoses, or treatment records to an integration not on the approved PHI storage list. Reference the 'Approved PHI Destinations' knowledge document." ### Internal authentication standards > "Verify that every API endpoint performing data mutations checks the caller's role against the required permission level. Flag endpoints that skip authorization checks." ### Data handling policies > "Check that applications do not export, log, or display raw payment card numbers. Ensure any refund or chargeback workflow includes approval steps and audit logging." ### Architecture standards > "Confirm that no application makes direct database queries from frontend components. All data access must go through backend APIs." ## What builders see When a Policy Agent completes, builders see it in their publish readiness checklist: ```text theme={null} PHI Storage Agent Blocked (2 findings) ``` Clicking into the report shows each finding with: * **What the agent found**: a clear explanation of the policy violation * **Evidence**: the specific code, configuration, or pattern that triggered the finding * **Location**: where in the application the issue exists * **Fix with Clark**: one-click remediation for eligible findings If Clark cannot fix a finding, the builder can escalate to an admin. Authorized admins can override a blocking agent when appropriate. ## Billing Policy Agents consume GAUs from your organization's shared GAU pool, the same as other Clark AI interactions. Usage appears in your [billing dashboard](/admin/self-serve-plan) under agent usage. ## Audit and RBAC Every agent run, finding, remediation attempt, escalation, and admin override is recorded as an [audit log](/admin/audit-logs) event. Admins get a full history of what was checked, what was found, and what action was taken. RBAC controls who can configure agents and set blocking thresholds, view reports and findings, escalate blocked findings, and force-push past a blocking agent. ## Related * [Code Security](/admin/code-security/index): built-in supply chain, static analysis, and Security Agent checks * [Knowledge](/building-with-clark/knowledge/index): guide Clark while it writes code, so fewer findings appear at publish time # Self-serve plans Source: https://docs.superblocks.com/admin/self-serve-plan Learn how Teams plan GAUs work, what's included, how to buy packs, and how to set up automatic or one-time GAU refills ## How GAUs work [Governed Agent Units (GAUs)](/admin/billing-overview#what-is-a-governed-agent-unit) are used across Clark (Superblocks' AI agent) and other governance and AI features. Each AI interaction consumes GAUs based on the complexity of the request. Here are some example prompts and their cost: | User prompt | Work done | GAUs used | | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | Add a header section with title and subtitle | Creates a reusable header component and applies existing page typography styles | 1 | | Change the top navigation background to black | Updates navigation styles and verifies contrast on existing text/icons | 2 | | Connect Salesforce opportunities and show a table + column chart | Explores the data with sample queries in Salesforce, identifies the right object and fields with the user, then implements both a table and chart | 4 | | Build a full sales dashboard from this schema | Generates a step-by-step plan, builds layout/components, connects data, and validates the final app | 8 | ## Included GAUs Teams plans use an **organization-level GAU pool** shared by all builders. You are not charged per builder seat. Additional org-level GAU packs are available for purchase. All GAUs reset monthly. ## GAU packs **Org-level top-ups:** Purchase GAUs that can be shared across all users in your organization | GAUs | Cost per month (Annual plan) | Cost per month (Monthly plan) | | ------------- | --------------------------------------------------- | --------------------------------------------------- | | 100 GAUs | **\$100** /month | **\$125** /month | | 250 GAUs | **\$250** /month | **\$313** /month | | 500 GAUs | **\$500** /month | **\$625** /month | | 1,000 GAUs | **\$1000** /month | **\$1250** /month | | 2,500 GAUs | **\$2500** /month | **\$3125** /month | | Custom volume | [Contact Sales →](mailto:pricing@superblockshq.com) | [Contact Sales →](mailto:pricing@superblockshq.com) | GAU packs are billed in-line with your billing schedule. [Contact sales](mailto:pricing@superblockshq.com) for higher volumes. ## Usage tracking Monitor spend and usage on [Plan & Usage](/admin/plan-and-usage): charts, group-by User / App / Day, checkpoint-level rollup, and deployed-app charges. Configure limits, alerts, and Teams refills on [Spend management](/admin/spend-management). ## GAU refills GAU refills are available on the **Teams** plan. Enterprise customers manage spending through [Spend management](/admin/spend-management) controls. When your shared GAU pool runs low, Superblocks can automatically purchase more GAUs, or you can buy a one-time top-up on demand. Navigate to **Organization Settings > Spend management** to configure refills. ### Automatic GAU refills Automatic refills help your team keep building when the pool runs low. When your GAU balance drops below a threshold you set, Superblocks automatically purchases additional GAUs using the payment method on file. #### Setting up automatic refills 1. Toggle **"Automatically purchase more GAUs when running low"** to enable auto-refills 2. Set a **Refill threshold**: the GAU balance at which a refill is triggered 3. Set a **Refill amount**: how many GAUs to purchase each time 4. Set a **Maximum refill amount**: a monthly cap on total automatic refill spending Refills are charged to the default payment method on file. You can pause automatic refills at any time by toggling the setting off. #### How automatic refills work When enabled, Superblocks monitors your organization's shared GAU pool. Once the balance drops to or below your configured threshold, a refill is triggered automatically: 1. The system checks your remaining GAUs against the **Refill threshold** 2. If the balance is at or below the threshold, it charges the **Refill amount** to your payment method 3. New GAUs are added to your shared pool immediately 4. Refill activity is logged in the **Refill history** table at the bottom of the page The **Maximum refill amount** acts as a monthly safety net. Even if usage spikes, automatic refills will not exceed this cap within a single billing cycle. ### One-time GAU purchases You can purchase a one-time GAU top-up from the Spend management page without enabling automatic refills. Click **"purchase a one-time refill"** in the GAU refills section to add GAUs immediately. One-time purchases appear in the Refill history table with the source marked accordingly. See [GAU packs](#gau-packs) for available pricing. ### Spend limits Teams plans also support per-user spend limits to control how GAUs are distributed across your team. See [Spend management](/admin/spend-management) for details on setting default and custom per-user limits. ### Refill history The Spend management page includes a refill history table that shows all GAU purchases, both automatic and one-time. Each entry includes: * Date and time of the refill * Number of GAUs added * Source (automatic or manual) * Payment status # Spend management Source: https://docs.superblocks.com/admin/spend-management Control GAU spending with organization-wide limits, per-user budgets, and programmatic management Superblocks gives administrators control over GAU and dollar spend. From the [**Spend Management**](https://app.superblocks.com/spending) page in organization settings, you can set organization-wide caps, assign per-user budgets, configure refill behavior (Teams), and set spend alerts. Spend Management is available on Enterprise and Teams plans. For charts, checkpoint-level usage, and deployed-app charges, use [Plan & Usage](/admin/plan-and-usage) instead. Spend Management overview ## Spend limits Spend limits prevent unexpected charges by capping usage at both the organization and individual user level. You can set org-wide overage spending limits, which are enforced based on your plan's billing cycle (monthly or annual). You can also set monthly per-user spend limits. Both budgets reset automatically at the start of each period. ### Maximum contract overage Enterprise organizations can set an **overage cap**: the maximum additional usage your team can consume beyond your contractual commit. This is your primary guardrail against runaway spending if your team exceeds your committed usage. Setting a maximum overage limit ### Default usage limit (monthly) Set a default allowance that applies to every user in your organization. This is the maximum any individual user can consume per month. Per-user limits always reset monthly, regardless of your plan's billing cycle. 1. In the **Spend limits** section, click **+** next to **Default usage limit (monthly)** 2. Enter the limit 3. The limit takes effect immediately for all users without a custom override ### Custom per-user usage limits Override the default limit for specific users who need more (or fewer) GAUs or dollars. 1. Click **+** next to **Custom per-user usage limits** 2. Select a user from the dropdown, including pending invitees who have not accepted yet 3. Set their individual limit Custom limits take precedence over the default. When a user with a pending invite accepts, their pre-configured limit applies immediately; no additional admin action is needed. Spend Limits with configured overage and per-user budgets Adding a custom per-user limit For Enterprise dollar-commit contracts, limits and usage displays are shown in dollar amounts instead of GAUs. ## What happens when a limit is reached When a user or organization reaches a configured spend limit: * AI-powered features (Clark and other AI interactions) are paused for the affected scope * Users see a notification explaining that their GAU limit has been reached * Administrators can increase limits or purchase additional GAUs to resume usage * Limits reset automatically at the start of each period (monthly for per-user limits; your billing cycle for the org-wide overage cap) ## Programmatic spend management via MCP You can monitor spending and configure limits programmatically using the [Superblocks MCP server](/admin/mcp-server). This is useful for automated monitoring, integrating with internal tools, or managing limits at scale. ### Available tools | Tool | Description | | --------------------------------- | ------------------------------------------------------------------------------------------------------ | | `get_billing_plan_summary` | Get current plan details including GAU allocation, usage, billing cycle dates, and deployed app counts | | `get_billing_usage_daily` | Get daily GAU usage for a date range — one row per day with total GAUs consumed | | `get_billing_usage_records` | Get per-user GAU usage records for a date range, including top consumers | | `list_billing_usage_limits` | View all configured spend limits — organization-wide and per-user | | `update_org_billing_usage_limit` | Set or update the organization-wide GAU overage cap | | `update_user_billing_usage_limit` | Set or update a per-user GAU limit, or configure the default limit for all users | All billing MCP tools require the `billing:manage` permission. ### Example: Check current usage Ask your AI coding agent: ``` What's our current GAU usage this billing cycle? ``` The agent will call `get_billing_plan_summary` and return your current usage, remaining GAUs, and billing cycle dates. ### Example: Set a per-user limit ``` Set a default per-user limit of 50 GAUs per month for my Superblocks org. ``` The agent will call `update_user_billing_usage_limit` with `is_default: true` and `credit_limit: 50`. ### Example: Monitor daily usage trends ``` Show me daily GAU usage for the past 30 days. ``` The agent will call `get_billing_usage_daily` with the appropriate date range and return a breakdown of daily consumption. ## Spending notifications New Spend alerts notify administrators by email when usage approaches configured thresholds, so you can take action before hitting a billing surprise. Configure alerts from the **Spend alerts** section at the bottom of the Spend Management page. Spend alerts are rolling out progressively. If you don't see the Spend alerts section on your Spend Management page, contact support to have it enabled for your organization. ### Alert types Superblocks supports four alert types. The types available to your organization depend on your plan: | Alert type | Description | TEAMS | Enterprise | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----- | ---------- | | **Organization spend** | Fires when total org usage crosses a threshold (percentage of allocation, GAUs used, or GAUs remaining) | ✓ | ✓ | | **Per-user spend** | Fires when an individual user's usage crosses a GAU threshold | ✓ | ✓ | | **Overage spend** | Fires when overage consumption crosses a specified threshold. Relevant for Enterprise plans. | — | ✓ | | **Refill spend** | Fires when cumulative GAU refill spending crosses a threshold in the current cycle. Relevant for pay-as-you-go plans (Teams). | ✓ | — | Enterprise contracts denominated in dollars (dollar commit) display all thresholds and usage in dollar amounts instead of GAUs. ### Configuring alerts 1. Navigate to **Organization Settings > Spend Management** 2. Scroll to the **Spend alerts** section 3. Click **+ Add alert** 4. Choose an alert type — only types available on your plan are shown 5. Set one or more thresholds (for example, notify at 80% and 100% of your allocation) 6. Save the alert Alerts are evaluated in real time as usage is recorded. When a threshold is crossed, an email is sent to all organization administrators. Each threshold fires at most once per billing cycle — it re-arms automatically when a new cycle begins. ### Threshold units The units available depend on the alert type: * **Organization spend:** percentage of allocation, GAUs used, or GAUs remaining * **Per-user spend:** GAUs consumed by a single user * **Overage spend:** overage GAUs consumed (or dollars, on dollar-commit plans) * **Refill spend:** GAUs or dollars spent on refills ### Delivery Spend alerts are delivered via email to all organization administrators. Per-user spend alerts also notify the individual user who triggered the threshold. # Superblocks on AWS Source: https://docs.superblocks.com/admin/superblocks-on-aws/aws How Superblocks maps to AWS services — Aurora PostgreSQL, Bedrock, S3, and more Superblocks on AWS means your builders create apps while your data, inference, and storage stay within your existing AWS security boundary. With [Cloud-Prem](/enterprise/cloud-prem/aws), the entire Superblocks platform runs in your AWS account — control plane, data plane, inference, databases, and storage. With [Hybrid](/enterprise/hybrid-architecture/overview), Superblocks manages the control plane while you run the data plane in your AWS network and integrate with your AWS services — Aurora PostgreSQL for app databases, Bedrock for App AI, S3 for file storage — so your data stays on AWS infrastructure you control. ## Platform mapping | Superblocks feature | AWS service | Description | | -------------------------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Database](/admin/superblocks-on-aws/database) | **Amazon Aurora PostgreSQL** | Each app gets its own managed PostgreSQL database on Aurora PostgreSQL, with automatic schema migrations on deploy. Aurora PostgreSQL is the only engine Superblocks Database provisions | | [Inference](/admin/superblocks-on-aws/inference) | **Amazon Bedrock** | Clark AI runs inference through Bedrock, burning down your existing AWS commitment and reducing Clark GAU usage | | [App AI](/integrations/app-ai) | **Amazon Bedrock** | Runtime AI features in deployed apps route through Bedrock using models and regions you control | | [File Store](/admin/superblocks-on-aws/file-store) | **Amazon S3** | Each app gets its own isolated S3 bucket for file uploads, reports, and other unstructured data | ## What this means for your organization **Burn down your AWS commitment.** Clark inference, app databases, and file storage all run on AWS resources, contributing to your existing Enterprise Discount Program (EDP) or committed spend, and reducing Clark GAU usage. Also purchasing Superblocks through [AWS Marketplace](/admin/superblocks-on-aws/aws-marketplace) draws down 100% of your Superblocks spend against your AWS commitment and earns AWS credits on top. **Data stays in your security boundary.** Whether you choose Cloud-Prem or Hybrid, your application data, AI inference, and file storage remain on AWS infrastructure inside your approved security boundary. No data leaves your network for processing. **Govern with existing policies.** Superblocks integrates with your existing IAM policies, VPC network controls, and security groups. No new governance model to adopt. ## Deployment options Superblocks offers multiple deployment models on AWS: | Model | Description | Learn more | | -------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Hybrid** | Data plane runs in your AWS VPC; control plane managed by Superblocks | [Hybrid on AWS ECS/Fargate](/enterprise/hybrid-architecture/deployment/aws_ecs_fargate) | | **Cloud-Prem** | Fully managed single-tenant deployment in your AWS account | [Cloud-Prem on AWS](/enterprise/cloud-prem/aws) | ## Get started 1. Configure your [database backend](/admin/superblocks-on-aws/database) to use Amazon Aurora PostgreSQL 2. Point Clark inference at [Amazon Bedrock](/admin/superblocks-on-aws/inference) 3. Set [App AI](/integrations/app-ai) to route runtime AI through Bedrock 4. Configure [file storage](/admin/superblocks-on-aws/file-store) to use S3 # AWS Marketplace Source: https://docs.superblocks.com/admin/superblocks-on-aws/aws-marketplace Purchase Superblocks through the AWS Marketplace to earn AWS platform credits, draw down on your AWS commitment, and accelerate procurement. Superblocks is available as a Private Offer on **AWS Marketplace**. Transacting through Marketplace gives your organization three direct benefits over a standard direct purchase. ## Benefits ### 2% earned in AWS credits Receive AWS platform credits worth **2%** of the total contract value for new business and **1%** for renewals, applied directly to your AWS bill. These credits are made available through Superblocks' standing in the AWS Marketplace Private Offer Promotion Program (MPOPP), and are applied in addition to any PPA discounts or existing AWS commitments you already have in place. ### 100% drawdown on AWS commitment Purchasing Superblocks through AWS Marketplace gives you two distinct financial benefits: **100%** of your Superblocks spend, dollar-for-dollar, counts toward your Private Pricing Agreement (PPA) drawdown (up to your negotiated Marketplace retirement allowance), and the underlying infrastructure Superblocks runs on (compute, database, inference, storage) continues to receive your existing PPA discounts and counts **100%** toward your AWS consumption commitment. ### Accelerate budget approval from your CFO Skip duplicate vendor onboarding and a second procurement cycle. Once commercial terms are finalized, Superblocks issues a Private Offer through AWS Marketplace for **one-click approval** by your authorized AWS account administrator — no separate MSA or invoicing process required. # Superblocks Database Source: https://docs.superblocks.com/admin/superblocks-on-aws/database Give every app its own managed AWS Aurora PostgreSQL database on your infrastructure with automatic schema migrations on deploy ## Overview Nearly every app built with AI needs a database. The moment a builder asks Clark to "track requests," "store approvals," or "save user preferences," that app needs persistent storage. Without a native database, this creates a problem: either IT provisions and manages databases manually for every app — which does not scale when hundreds of builders are vibe coding — or builders are forced to use external storage that moves data outside your network, and manage the databases themselves. Superblocks Database solves both problems: * **Every app gets its own Aurora PostgreSQL database automatically.** Builders describe what they need, and Clark provisions an isolated database on your infrastructure. No tickets, no manual setup, no database expertise required. * **Data never leaves your network.** Databases run on **AWS Aurora PostgreSQL** inside your own VPC. Superblocks orchestrates the provisioning but your data stays on your infrastructure. * **Development and production are separated by default.** Builders who have never managed a database do not need to understand environments. Each app gets a separate database per environment, and Superblocks handles schema migrations on deploy. Test data never reaches production. Each app gets its own isolated database, and those databases are hosted on shared Aurora PostgreSQL clusters that your admins size. Pooling many apps onto a cluster is what keeps the cost predictable — the default is 100 apps per cluster, and Superblocks adds another cluster as the pool fills. When a builder asks Clark for any feature that requires persistence, the platform creates that app's database automatically. ## How it works ### 1. Your admins turn it on once Enabling Superblocks Database is an infrastructure change, not a settings toggle. Your admins run a Terraform module in your AWS account to create the IAM roles and the state bucket, add the database configuration to the data plane (as ECS task environment variables or Helm values), and then provision the first Aurora cluster once from the Superblocks admin panel. From then on, the admin panel shows that configuration read-only, because it reflects what the running data plane is actually configured with. Every database operation after that is triggered from your data plane, running code you control. See [Setup](/admin/superblocks-on-aws/database-setup) for the full walkthrough and the exact AWS permissions involved. ### 2. Clark provisions a development Aurora PostgreSQL database When a builder asks Clark to store data — for example, "add a database to track commission rate requests": * Clark tells your data plane to provision a database * Your data plane provisions an isolated development database for that app (via code you control) * Clark proposes the schema (tables, columns, indexes) for the database and runs these migrations through your data plane * Clark wires up the APIs to read and write data The builder never leaves the Superblocks editor. They describe the feature, and Clark handles provisioning and schema design. ### 3. Each environment gets its own database Development and production are separate databases, not two views of one. Builders work against the development database while editing, so test data has no path into production. Databases are organized the way your data planes are: in the common setup where staging and production run separate data planes, each app gets one isolated database per environment. This separation is automatic. Builders do not need to configure it. ### 4. Schema migrations run on deploy Clark keeps the schema in the application's own code as `.sql` migration files, so the schema is versioned alongside the app. When a builder publishes, Superblocks automatically: * Creates the production database if it does not already exist * Applies the app's migrations to it, producing the same schema with none of the development data * Blocks the deploy until the production database and its migrations are ready There is no manual migration step. The platform handles the full lifecycle from development through production. ## What builders experience From the builder's perspective, database provisioning is invisible. They prompt Clark to add a feature that needs persistent data, and Clark creates the database, writes the schema, and builds the APIs. When they publish, the production database is ready with a clean schema. This gives every builder a persistent data store for their app, backed by your organization's infrastructure. # Superblocks Database Reference Source: https://docs.superblocks.com/admin/superblocks-on-aws/database-reference Implementation details behind Superblocks Database: AWS resources, IAM scoping, and the mechanics behind setup choices that can't be changed later This page documents the mechanics behind Superblocks Database: the AWS resources it creates, how IAM permissions are scoped, and what's behind the setup choices that can't be changed later. If you're doing initial setup, start with [Setup](/admin/superblocks-on-aws/database-setup). ## Setup decisions Three values are fixed once a data plane has databases. There's no automated migration path today — changing any of them requires manual recovery. ### Agent name The agent name is the `agents` map key for a data plane — `agents = { "" = { ... } }` — reused as Fargate `agent_name` or Helm `superblocks.agentName`. It's the identity Superblocks uses everywhere the data plane touches AWS: * **IAM scoping.** Every create and mutate is gated on the tag `AgentName=`, stamped by the lifecycle worker on every resource it creates. * **Role and policy naming.** Each data plane gets its own lifecycle worker and connector role. * **OpenTofu state isolation.** `app_db_prereqs` derives this data plane's state prefix from it (default `app-db/`), scopes S3 permissions to that prefix, and exports it as `agents[""].key_prefix`. A name or prefix that doesn't match what created the roles fails every call with `AccessDenied`. Changing the agent name means Terraform destroys and recreates the IAM roles under the new name — the data plane can't manage its database pool again until it's redeployed with the new role ARNs. No data is lost, but it's a coordinated migration, not a rename. ### Data tag names Database and role names are derived from a hash of the tag: `sbndb__` for the database, `sbndb___runtime` for its role. `` is the first 16 hex characters of `SHA-256(lowercase(tag))`; `` is a 24-hex hash of the application ID. The connector role's permissions are scoped to that pattern, so renaming a tag orphans every existing database and role under the old name. Tag names must be non-empty and unique across all agents in the module invocation. ### VPC Every IAM policy created for a data plane is scoped to its VPC. Changing it means none of the existing roles can act on resources in the new VPC. ## How databases go from edit to deployed A database is created when a builder with database creation permission asks for one in the Superblocks editor. If an existing Aurora PostgreSQL cluster has capacity under your scaling settings, Superblocks queues a task to create an isolated logical database on that cluster. Your data plane picks tasks up from the queue and applies them. Clark generates the database schema and stores it as `.sql` files in the application code. Once the database is ready, Clark queues a task for the data plane to run the migrations. Databases follow your data plane layout and the [data tags](/development-lifecycle/build/data-tags) each data plane serves. When an app is deployed, Superblocks can create a separate database for the deploy-time data tag before the deploy finishes. The diagram below traces one app's database end to end. While a builder is still editing, Clark asks for a database, your data plane creates it, and Clark's generated schema is applied. On deploy, the same sequence can run again against a separate database for the deploy-time data tag. Superblocks only queues work; your data plane claims it and calls AWS. ```mermaid theme={null} sequenceDiagram autonumber participant Builder participant Clark as Clark participant SB as Superblocks control plane participant DP as Data plane lifecycle worker participant AWS as Your AWS account Builder->>Clark: Ask for a feature that needs persistent data Clark->>SB: Request a database for this app SB->>SB: Queue a lifecycle task DP->>SB: Claim the pending task DP->>AWS: tofu apply: create isolated logical database AWS-->>DP: Database ready DP->>SB: Ready callback Clark->>Clark: Generate schema as .sql files in the app code Clark->>SB: Queue a migration task DP->>AWS: Apply migrations to the edit-time database Builder->>SB: Deploy the app SB->>DP: Create the deploy-time database, then apply migrations DP->>AWS: tofu apply plus migrations SB-->>Builder: Deploy proceeds once the deploy-time database is ready ``` ## What Superblocks creates in your AWS account Resources arrive in two waves with very different lifetimes. Setup creates a small, fixed set of control resources that live as long as the feature is enabled. Everything else is created on demand as the pool grows, and those are the resources you manage day to day. ### At setup: control resources The Terraform module creates these once. They are inexpensive to keep, and removing them disables provisioning. **Lifecycle worker IAM role**: your data plane assumes this role to manage database infrastructure. Its permissions are narrowly scoped: every mutation (create, modify, delete) is tag-gated, so the role can only act on resources that Superblocks itself tagged at creation time. It cannot touch resources in other VPCs or resources it did not create. See [IAM permissions](#iam-permissions) for the full breakdown. **Connector IAM role**: one role per data plane. This is the identity your data plane uses to reach app databases at query time. To run a query, the data plane assumes this role and uses the resulting credentials to sign a short-lived RDS IAM auth token, which PostgreSQL accepts in place of a password. Provisioning creates the PostgreSQL role the token authenticates as and grants it `rds_iam`; the PostgreSQL role name follows `sbndb___runtime` (see [Connector role](#connector-role)), and is unrelated to the connector role's ARN. The trust policy limits who can assume this role to the lifecycle worker role for that data plane. See [Connector role](#connector-role) for how the permissions are narrowed on each connection. **Enhanced Monitoring IAM role**: one account-level role shared by every App Database cluster and instance. RDS assumes this role to publish operating-system metrics. The lifecycle worker can pass only this role, and only to `rds.amazonaws.com`. **S3 bucket**: stores OpenTofu state so Superblocks can manage your database resources over time (modify, delete, track drift). Key properties: * One bucket per account and region * Versioning enabled, so state can be recovered if corrupted * Public access blocked * Encrypted at rest with **SSE-S3** by default (AWS-managed keys, no KMS charges). Optionally bring your own KMS key via `kms_key_arn` to use SSE-KMS. When provided, the lifecycle worker IAM policy scopes KMS access to that specific key ARN only * Superblocks reads and writes to this bucket; you own and retain it * Each data plane is IAM-scoped to its own prefix (default `app-db/`, exported as `agents[""].key_prefix`). State keys follow `{key_prefix}/{tag}/{resource_key}.tfstate` ### As the pool grows: one set per Aurora cluster `pool.max_databases` (Fargate) / `pool.maxDatabases` (EKS) caps how many app databases land on one cluster before another is added to the pool. Lowering it spreads apps across more clusters, which shrinks the blast radius of a failover or an engine patch and raises your baseline cost; raising it does the reverse. Along with the ACU range, this is the main control over what the pool costs as it grows. Your data plane creates the following each time it adds a cluster to the pool (first when you click **Provision**, and again whenever existing clusters reach `max_databases`): * **Aurora PostgreSQL cluster and its instances**: named `sb-{hash}`, IAM authentication enabled, public accessibility disabled, storage encrypted at rest, and the master password managed by AWS Secrets Manager so there are no plaintext passwords * **CloudWatch log group**: a per-cluster `/aws/rds/cluster//postgresql` group that retains exported PostgreSQL logs for 30 days * **DB cluster parameter group**: logs every statement running for at least 5 seconds, samples 10% of statements running between 1 and 5 seconds, and excludes bound parameter values * **DB subnet group**: scoped to the subnets you specified in `physical_module_inputs` * **Security group and its ingress/egress rules**: controls which sources (security groups or CIDRs) can reach the database on port 5432. The security group and each rule are separate AWS resources and both carry the tags below. Individual app databases are logical databases inside these clusters, each with its own PostgreSQL role. They are not separate AWS resources, so they do not appear in the RDS console as their own entries. ### Observability defaults The default configuration provides the following signals in your AWS account: * Standard RDS CloudWatch metrics * Enhanced Monitoring at 60-second resolution through the account- and region-level `RDSOSMetrics` CloudWatch Logs group, with one log stream per database instance. Its retention is independent of the per-cluster PostgreSQL log group's 30-day setting * Database Insights Standard, with Performance Insights retained for 7 days * PostgreSQL logs exported to CloudWatch Logs with 30-day retention * PostgreSQL diagnostic logs for lock waits and deadlocks, temporary files larger than 64 MiB, checkpoints, and autovacuum operations running at least 5 seconds * Slow-query logging for every statement running at least 5 seconds and a 10% sample of statements running between 1 and 5 seconds. Statements under 1 second are not duration-logged. Bound parameter values are excluded, although the parameterized statement text is retained * `pg_stat_statements` tracking for top-level statements. Its storage is bounded and shared across the cluster, so older or less-used entries can be evicted; the module does not fix a universal entry limit Enhanced Monitoring is optional — see the `monitoring_interval` comment in [Step 1](/admin/superblocks-on-aws/database-setup#step-1-run-the-terraform-module). Settings declared in the physical module inputs or supplied by its defaults—including log retention and PostgreSQL parameters—are managed through OpenTofu, so a later lifecycle apply can revert manual console changes. Superblocks does not ingest these signals or monitor your databases on your behalf. Your organization controls access to CloudWatch, pays any associated AWS charges, and owns the dashboards, alarms, subscriptions, and incident-response processes it builds on top. ### How everything is tagged Every App Database AWS resource carries two kinds of tags. **IAM scoping tags** (required for the lifecycle worker to mutate the resource): * `AgentName={agents-map-key}` — the [agent name](/admin/superblocks-on-aws/database-reference#agent-name) for this data plane (Terraform `agents` map key, Fargate `agent_name`, or Helm `superblocks.agentName`) * `ManagedBy=superblocks-app-database-lifecycle` * `Vpc={your-vpc-id}` The IAM policies only allow create/modify/delete on resources carrying all three. The worker stamps `AgentName` itself; physical modules merge `ManagedBy`; `Vpc` comes from your networking inputs. **Ownership and partnership tags** (required on every Superblocks-created resource, including runtime Aurora): * `superblocks:owned=true` * `aws-apn-id=pc:ctelqp437y3cvjkv5rv0z2w4f` These identify Superblocks-managed resources and attribute them to Superblocks' AWS Partner Network ID. They do **not** change who pays the bill or which AWS account owns the resources — that remains your account. `aws-apn-id` is a fixed Superblocks constant (`pc:ctelqp437y3cvjkv5rv0z2w4f`); copy it verbatim — it is not per-account. `app-db-prereqs` enforces both keys on setup resources. The Fargate `app-db` module merges the same pair into runtime module inputs, overwriting conflicting caller values. On EKS, the Helm chart does **not** inject them — set both keys under `databaseLifecycle.physicalModuleTags` (see [Step 1](/admin/superblocks-on-aws/database-setup#step-1-run-the-terraform-module)). Without them, IAM create on runtime Aurora, RDS, subnet groups, and security groups fails with `AccessDenied`. The lifecycle worker IAM policy also denies removing either key from runtime resources. The lifecycle worker IAM policy also denies removing any of the five keys above (`AgentName`, `ManagedBy`, `Vpc`, `superblocks:owned`, and `aws-apn-id`), including via named Deny Sids (`DenyRemoveProtectedTags` / `DenyDeleteProtectedTags` / `DenyUntagProtectedTags`) so AccessDenied is attributable. EC2 `DenyDeleteProtectedTags` is further scoped with `AgentName` / `ManagedBy` / `Vpc` ResourceTags so attaching policies via `existing_role_name` cannot Deny `DeleteTags` on unrelated security groups. Find everything the feature manages with a Resource Group or the CLI: ```bash theme={null} aws resourcegroupstaggingapi get-resources \ --tag-filters Key=ManagedBy,Values=superblocks-app-database-lifecycle # Or filter on ownership: aws resourcegroupstaggingapi get-resources \ --tag-filters Key=superblocks:owned,Values=true ``` ### S3 state bucket properties The bucket is created unconditionally: one per account and region, shared across all data planes in the same module invocation. Default naming is `sb-app-db--`, where the `sb-app-db` prefix comes from the `s3_name_prefix` variable. When creating it manually, configure the following properties: | Property | Required value | Notes | | ---------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Versioning | Enabled | Required for state recovery | | Block public access | All four settings enabled | `block_public_acls`, `block_public_policy`, `ignore_public_acls`, `restrict_public_buckets` | | Server-side encryption | SSE-S3 (default) or SSE-KMS | SSE-KMS only when `kms_key_arn` is provided; use the same key ARN supplied to the module | | S3 bucket key | Disabled | Bucket keys cache a per-bucket KMS data key to reduce KMS API call volume. The module disables this (`bucket_key_enabled = false`). This is separate from `kms_key_arn`; you can use SSE-KMS with a customer-managed key and still have bucket keys off. | | Non-current version expiration | 90 days | Keeps state recoverable without unbounded storage growth | | Abort incomplete multipart uploads | 7 days | | | Bucket policy | None | Access is controlled entirely via the IAM policies above; no explicit bucket policy is required | ## Security | What | Details | | ------------------- | ----------------------------------------------------------------------------------------------------------------------- | | Authentication | IAM token via `rds-db:connect`: no passwords stored or rotated | | Network | The database lives in your private subnets; `publicly_accessible = false` is enforced by IAM policy | | Encryption (S3) | SSE-S3 by default (AWS-managed keys); optionally SSE-KMS with your own key via `kms_key_arn` | | Encryption (Aurora) | Storage encrypted at rest; TLS in transit | | IAM scope | All lifecycle worker mutations are tag-gated to resources Superblocks created in your VPC | | State storage | OpenTofu state lives in your S3 bucket; Superblocks does not retain a copy | | Master credentials | Managed by AWS Secrets Manager; the lifecycle worker reads them by ref, so there is no plaintext in Superblocks systems | ### IAM permissions #### Lifecycle worker role Your data plane runs as this role to manage database infrastructure. Its policies cover state, RDS provisioning and mutation, EC2 networking, Secrets Manager, and observability. **State backend policy.** Scoped exclusively to the S3 bucket the Terraform module creates, with no wildcards: * **S3**: `ListBucket` (prefix-conditioned), `GetObject`, `PutObject`, `DeleteObject` under that agent's `key_prefix` in the state bucket only * **KMS** (only when `kms_key_arn` is provided): `Encrypt`, `Decrypt`, `GenerateDataKey` on the specific key ARN. Superblocks cannot use any other KMS key in your account. **RDS provisioning policy.** This is the largest policy. **Every mutation is tag-gated**: the lifecycle worker can only create, modify, or delete resources carrying `AgentName={agent-map-key}`, `ManagedBy=superblocks-app-database-lifecycle`, and `Vpc={your-vpc-id}`. Create actions must supply all three tags as request tags. Delete and modify actions require all three tags to already exist on the target resource. The IAM policy only permits removing tags other than `AgentName`, `ManagedBy`, `Vpc`, `superblocks:owned`, and `aws-apn-id`, so the scoping and ownership tags cannot be stripped. An explicit Deny Sid (`DenyRemoveProtectedTags` / `DenyDeleteProtectedTags`) makes that failure attributable in IAM diagnostics. Additional constraints enforced in the policy: * RDS instance ARNs are restricted to the `sb-*` namespace, so Superblocks cannot modify your existing RDS instances * `rds:PubliclyAccessible` must be `false` on all create actions: the policy rejects any create that asks for a public endpoint * `rds:ManageMasterUserPassword` must be `true` on standalone RDS creates, so master credentials are always managed by Secrets Manager and never set as a static password. This condition also discriminates standalone RDS creates from Aurora cluster member creates: Aurora member creates do not pass this key (the master password is inherited from the cluster), so `rds:ManageMasterUserPassword` evaluates to false and only the Aurora member statement matches. * `rds:DatabaseEngine` is pinned to `postgres` (standalone RDS) and `aurora-postgresql` (Aurora cluster) at create time, so the lifecycle worker cannot provision any other engine type * `rds:StorageEncrypted` must be `true` on standalone RDS and Aurora cluster creates. Storage encryption is enforced by IAM at create time, not only by module configuration. * Security group mutations are scoped to the same `AgentName`, `ManagedBy`, and `Vpc` tag triple * EC2 security group creation is additionally scoped to the specific VPC ID via the `ec2:VpcID` condition, so Superblocks cannot create resources in other VPCs in your account * KMS access for RDS storage encryption is gated on `aws:CalledVia: rds.amazonaws.com`, so Superblocks cannot use your KMS keys directly Allowed describe and list actions (`DescribeDBInstances`, `DescribeDBSubnetGroups`, `DescribeVpcs`, `DescribeSubnets`, and similar) are read-only and apply to `"Resource": "*"`. This is required by AWS, because describe APIs do not support resource-level restrictions, but no data is retained by Superblocks. **Master secrets policy.** Scoped to RDS-managed master secrets (`rds!db-*` and `rds!cluster-*` ARN prefixes): * **Read**: `GetSecretValue` and `DescribeSecret` on RDS-managed secrets tagged with `AgentName`, `ManagedBy`, and `Vpc`: the master credentials for databases Superblocks created * **Write** (create and tag): only allowed via `aws:CalledVia: rds.amazonaws.com`. Superblocks cannot directly create Secrets Manager secrets; only RDS can, on behalf of Superblocks. * **IAM**: `CreateServiceLinkedRole` scoped to `rds.amazonaws.com`. This is a one-time action required to create the RDS service-linked role if it does not already exist in your account. #### Connector role One connector role is created per data plane. The role grants `rds-db:connect` scoped to the DB users Superblocks provisions for that data plane: one statement per data tag, matching the pattern `sbndb__*_runtime` in your region. `` is the first 16 hexadecimal characters of the SHA-256 digest of the lowercased data tag (for example, `printf '%s' '' | shasum -a 256 | cut -c1-16`). The connector role can only authenticate as DB users that Superblocks created for the declared data tags. It cannot connect as any other DB user, or to databases in your account that Superblocks did not create. The trust policy limits who can assume the connector role to the specific lifecycle worker role ARN for that data plane. No other principal can assume it. #### How a connection is authenticated Neither the connector role's ARN nor the lifecycle worker's identity appears inside PostgreSQL. The database only ever sees a PostgreSQL role name and an auth token, and IAM decides whether that token is valid. The sequence for a single query is: 1. **Provisioning** creates the app's PostgreSQL role (`sbndb___runtime`, where `` comes from the data tag as described above and `` is a 24-hex hash of the application ID) and grants it `rds_iam`. That grant makes PostgreSQL delegate authentication for this role to IAM instead of checking a stored password. No password is ever generated for it. 2. **The data plane checks the target** against the connector role ARN it was configured with, and refuses the connection if they disagree. A compromised control plane cannot redirect the data plane at an IAM role its operator never approved. 3. **The data plane assumes the connector role**, attaching an inline session policy that allows exactly one action on exactly one resource: `rds-db:connect` on this cluster, as this one PostgreSQL role. The credentials it gets back are narrower than the connector role itself. 4. **It signs an RDS IAM auth token** for that PostgreSQL role with those session credentials, and connects using the token as the password, over TLS with full certificate and hostname verification. The effective permission on any given connection is the intersection of the two policies: the connector role's own policy bounds it to `sbndb__*_runtime` users for the declared data tags, and the per-connection session policy narrows that to the single user for the single app being served. One app's credentials cannot reach another app's database, even though both use the same connector role. ## Raw IAM policy JSON The Terraform module creates the following IAM resources per data plane. If your organization requires policies to be pre-approved or manually provisioned before Terraform can attach them, use the JSON below. `iam_name_prefix` prefixes the IAM role and policy names below, and `s3_name_prefix` prefixes the state bucket name. Both default to `sb-app-db`, which is what the example values show. Placeholders to substitute before use: | Placeholder | Example value | Description | | ----------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `` | `us-east-1` | AWS region | | `` | `123456789012` | 12-digit AWS account ID | | `` | `vpc-0123456789abcdef0` | VPC ID declared for this data plane | | ``, ``, … | `subnet-0123456789abcdef0` | Private subnet IDs for the Aurora subnet group | | `` | `sg-0123456789abcdef0` | Security group allowed to reach Aurora on port 5432 | | `` | `sb-app-db-us-east-1-123456789012` | S3 state bucket name (the `sb-app-db` prefix comes from `s3_name_prefix`) | | `` | `app-db/` | OpenTofu state prefix IAM-scoped to this data plane. Equals `module.app_db_prereqs.agents[""].key_prefix` (override via `agents[].key_prefix`). See [Agent name](/admin/superblocks-on-aws/database-reference#agent-name). | | `` | — (max 15 characters, lowercase alphanumeric, unique per AWS account) | [Agent name](/admin/superblocks-on-aws/database-reference#agent-name) for this data plane. Terraform `agents` map key; must also equal Fargate `agent_name` or Helm `superblocks.agentName`, and the `AgentName` tag on every resource the lifecycle worker creates. Used in IAM role and policy names. | | `` | `arn:aws:iam::123456789012:role/sb-app-db--lifecycle-worker-` | ARN of the lifecycle worker role | | `` | `arn:aws:iam::123456789012:role/superblocks-app-db-connector-` | ARN of the connector role (fixed `superblocks-app-db-connector-` name; not affected by `iam_name_prefix`) | | `` | `arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE` | EKS OIDC provider ARN (EKS only) | | `` | `oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE` | OIDC URL (the ARN above with `arn:aws:iam:::oidc-provider/` stripped) | | `` | `arn:aws:iam::123456789012:role/sb-app-db-enhanced-monitoring` | ARN of the shared Enhanced Monitoring role (the `sb-app-db` prefix comes from `iam_name_prefix`) | When creating these manually, create the lifecycle worker role first (it has no dependencies), then the connector role (its trust policy references the lifecycle worker role ARN), then create and attach all policies. Allows the ECS task service principal to assume the role. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Principal": { "Service": "ecs-tasks.amazonaws.com" } } ] } ``` Allows the data plane pod's service account to assume the role via OIDC web identity. `` is the OIDC provider URL without the ARN prefix (everything after `oidc-provider/`). The `sub` condition scopes trust to the specific Kubernetes service account. Adjust `namespace` and `service_account_name` if you deviate from the Superblocks defaults. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRoleWithWebIdentity", "Principal": { "Federated": "" }, "Condition": { "StringEquals": { ":aud": "sts.amazonaws.com" }, "StringLike": { ":sub": "system:serviceaccount:superblocks:superblocks-agent" } } } ] } ``` Allows the lifecycle worker to assume its connector role for RDS IAM authentication. Attached to the lifecycle worker role. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "AssumeAppDatabaseConnector", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": [""] } ] } ``` Allows the lifecycle worker to read and write OpenTofu state in the shared S3 bucket under that agent's `key_prefix` only (default `app-db/`; override via `agents[""].key_prefix`). Replace `` with the same string you wire into the data plane (see [Agent name](/admin/superblocks-on-aws/database-reference#agent-name)). `GetBucketLocation` / `GetBucketVersioning` live in a separate statement from `ListBucket` because those metadata APIs do not send `s3:prefix` and would fail closed if they shared the list condition. The last statement (`StateBucketKms`) handles bucket encryption. **Without a customer KMS key** (the default, SSE-S3), the resource is `"*"` and access is constrained to calls originating from S3, as shown below. **With a customer KMS key** (`kms_key_arn` set), replace `"Resource": "*"` with the specific key ARN and remove the `Condition` block entirely. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "StateBucketMetadata", "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:GetBucketVersioning" ], "Resource": "arn:aws:s3:::" }, { "Sid": "StateBucketList", "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::", "Condition": { "StringLike": { "s3:prefix": [ "/", "/*" ] } } }, { "Sid": "StateBucketObjectReadWrite", "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:DeleteObject", "s3:GetObject", "s3:GetObjectVersion", "s3:PutObject" ], "Resource": "arn:aws:s3::://*" }, { "Sid": "StateBucketKms", "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:DescribeKey", "kms:Encrypt", "kms:GenerateDataKey", "kms:ReEncryptFrom", "kms:ReEncryptTo" ], "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "aws:CalledVia": "s3.amazonaws.com" } } } ] } ``` Allows the lifecycle worker to describe RDS and Aurora resources globally (required by AWS, because describe APIs do not support resource-level restrictions) and to create new RDS and Aurora resources scoped to the `sb-*` namespace and the declared VPC. All create actions enforce tagging at request time, `publicly_accessible = false`, and `manage_master_user_password = true`. The `RdsCreateDbInstance` and `RdsCreateAuroraClusterInstance` statements both cover `rds:CreateDBInstance` but are cleanly discriminated: standalone RDS creates pass `rds:ManageMasterUserPassword = true` and Aurora member creates do not, so each request matches exactly one statement. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "RdsDescribe", "Effect": "Allow", "Action": [ "rds:DescribeDBClusterParameterGroups", "rds:DescribeDBClusterParameters", "rds:DescribeDBClusterSnapshots", "rds:DescribeDBClusters", "rds:DescribeDBEngineVersions", "rds:DescribeDBInstances", "rds:DescribeDBParameterGroups", "rds:DescribeDBParameters", "rds:DescribeDBSnapshots", "rds:DescribeDBSubnetGroups", "rds:DescribeGlobalClusters", "rds:DescribePendingMaintenanceActions", "rds:ListTagsForResource" ], "Resource": "*" }, { "Sid": "CreateRdsServiceLinkedRole", "Effect": "Allow", "Action": "iam:CreateServiceLinkedRole", "Resource": "*", "Condition": { "StringEquals": { "iam:AWSServiceName": "rds.amazonaws.com" } } }, { "Sid": "RdsCreateDbInstance", "Effect": "Allow", "Action": "rds:CreateDBInstance", "Resource": [ "arn:aws:rds:::db:sb-*", "arn:aws:rds:::subgrp:sb-*", "arn:aws:rds:::pg:*" ], "Condition": { "Bool": { "rds:ManageMasterUserPassword": "true", "rds:PubliclyAccessible": "false", "rds:StorageEncrypted": "true" }, "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "", "rds:DatabaseEngine": "postgres" } } }, { "Sid": "RdsCreateAuroraCluster", "Effect": "Allow", "Action": "rds:CreateDBCluster", "Resource": [ "arn:aws:rds:::cluster:sb-*", "arn:aws:rds:::cluster-pg:*", "arn:aws:rds:::subgrp:sb-*" ], "Condition": { "Bool": { "rds:ManageMasterUserPassword": "true", "rds:StorageEncrypted": "true" }, "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "", "rds:DatabaseEngine": "aurora-postgresql" } } }, { "Sid": "RdsCreateAuroraClusterInstance", "Effect": "Allow", "Action": "rds:CreateDBInstance", "Resource": [ "arn:aws:rds:::cluster:sb-*", "arn:aws:rds:::db:sb-*", "arn:aws:rds:::pg:*", "arn:aws:rds:::subgrp:sb-*" ], "Condition": { "Bool": { "rds:PubliclyAccessible": "false" }, "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "", "rds:DatabaseEngine": "aurora-postgresql" } } }, { "Sid": "RdsCreateParameterGroups", "Effect": "Allow", "Action": [ "rds:CreateDBClusterParameterGroup", "rds:CreateDBParameterGroup" ], "Resource": [ "arn:aws:rds:::cluster-pg:sb-*", "arn:aws:rds:::pg:sb-*" ], "Condition": { "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "RdsCreateDbSubnetGroup", "Effect": "Allow", "Action": "rds:CreateDBSubnetGroup", "Resource": "arn:aws:rds:::subgrp:sb-*", "Condition": { "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "RdsTagOnCreate", "Effect": "Allow", "Action": "rds:AddTagsToResource", "Resource": [ "arn:aws:rds:::cluster:sb-*", "arn:aws:rds:::cluster-pg:sb-*", "arn:aws:rds:::db:sb-*", "arn:aws:rds:::pg:sb-*", "arn:aws:rds:::subgrp:sb-*" ], "Condition": { "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" }, "StringEqualsIfExists": { "aws:RequestTag/aws-apn-id": "pc:ctelqp437y3cvjkv5rv0z2w4f", "aws:RequestTag/superblocks:owned": "true" } } }, { "Sid": "RdsTagAppSnapshotOnCreate", "Effect": "Allow", "Action": "rds:AddTagsToResource", "Resource": [ "arn:aws:rds:::cluster-snapshot:sb-*", "arn:aws:rds:::snapshot:sb-*" ], "Condition": { "StringEqualsIfExists": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "", "aws:RequestTag/aws-apn-id": "pc:ctelqp437y3cvjkv5rv0z2w4f", "aws:RequestTag/superblocks:owned": "true" } } }, { "Sid": "RdsEncryptedStorageKmsViaRds", "Effect": "Allow", "Action": [ "kms:CreateGrant", "kms:Decrypt", "kms:DescribeKey", "kms:GenerateDataKey" ], "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "aws:CalledVia": "rds.amazonaws.com" } } } ] } ``` Allows the lifecycle worker to modify, delete, snapshot, and retag RDS and Aurora resources it created. All mutations are gated on the `AgentName`, `ManagedBy`, and `Vpc` resource tags, so the lifecycle worker cannot modify any RDS resource it did not create. `RdsRemoveTagsExceptProtectedTags` only Allows removing non-protected tags. `DenyRemoveProtectedTags` is an explicit Deny that blocks removing `AgentName`, `ManagedBy`, `Vpc`, `superblocks:owned`, or `aws-apn-id`, so AccessDenied is attributable to that Sid. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "RdsMutate", "Effect": "Allow", "Action": [ "rds:DeleteDBCluster", "rds:DeleteDBClusterParameterGroup", "rds:DeleteDBInstance", "rds:DeleteDBParameterGroup", "rds:DeleteDBSubnetGroup", "rds:ModifyDBCluster", "rds:ModifyDBClusterParameterGroup", "rds:ModifyDBInstance", "rds:ModifyDBParameterGroup", "rds:ModifyDBSubnetGroup", "rds:RebootDBCluster", "rds:RebootDBInstance", "rds:ResetDBClusterParameterGroup", "rds:ResetDBParameterGroup" ], "Resource": [ "arn:aws:rds:::cluster:sb-*", "arn:aws:rds:::cluster-pg:sb-*", "arn:aws:rds:::db:sb-*", "arn:aws:rds:::pg:sb-*", "arn:aws:rds:::pg:*", "arn:aws:rds:::subgrp:sb-*" ], "Condition": { "BoolIfExists": { "rds:ManageMasterUserPassword": "true" }, "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" } } }, { "Sid": "RdsDeleteAuroraClusterFinalSnapshot", "Effect": "Allow", "Action": "rds:DeleteDBCluster", "Resource": "arn:aws:rds:::cluster-snapshot:sb-*", "Condition": { "StringEqualsIfExists": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "RdsCreateSnapshotFromManagedCluster", "Effect": "Allow", "Action": "rds:CreateDBClusterSnapshot", "Resource": "arn:aws:rds:::cluster:sb-*", "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" } } }, { "Sid": "RdsCreateAppClusterSnapshot", "Effect": "Allow", "Action": "rds:CreateDBClusterSnapshot", "Resource": "arn:aws:rds:::cluster-snapshot:sb-*", "Condition": { "StringEqualsIfExists": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "RdsCreateSnapshotFromManagedInstance", "Effect": "Allow", "Action": "rds:CreateDBSnapshot", "Resource": "arn:aws:rds:::db:sb-*", "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" } } }, { "Sid": "RdsCreateAppSnapshot", "Effect": "Allow", "Action": "rds:CreateDBSnapshot", "Resource": "arn:aws:rds:::snapshot:sb-*", "Condition": { "StringEqualsIfExists": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "RdsAddTagsToManagedResources", "Effect": "Allow", "Action": "rds:AddTagsToResource", "Resource": [ "arn:aws:rds:::cluster:sb-*", "arn:aws:rds:::cluster-pg:sb-*", "arn:aws:rds:::cluster-snapshot:sb-*", "arn:aws:rds:::db:sb-*", "arn:aws:rds:::pg:sb-*", "arn:aws:rds:::pg:*", "arn:aws:rds:::snapshot:sb-*", "arn:aws:rds:::subgrp:sb-*" ], "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" }, "StringEqualsIfExists": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "", "aws:RequestTag/aws-apn-id": "pc:ctelqp437y3cvjkv5rv0z2w4f", "aws:RequestTag/superblocks:owned": "true" } } }, { "Sid": "RdsRemoveTagsExceptProtectedTags", "Effect": "Allow", "Action": "rds:RemoveTagsFromResource", "Resource": [ "arn:aws:rds:::cluster:sb-*", "arn:aws:rds:::cluster-pg:sb-*", "arn:aws:rds:::cluster-snapshot:sb-*", "arn:aws:rds:::db:sb-*", "arn:aws:rds:::pg:sb-*", "arn:aws:rds:::pg:*", "arn:aws:rds:::snapshot:sb-*", "arn:aws:rds:::subgrp:sb-*" ], "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" }, "ForAllValues:StringNotEquals": { "aws:TagKeys": ["AgentName", "ManagedBy", "Vpc", "aws-apn-id", "superblocks:owned"] } } }, { "Sid": "DenyRemoveProtectedTags", "Effect": "Deny", "Action": "rds:RemoveTagsFromResource", "Resource": [ "arn:aws:rds:::cluster:sb-*", "arn:aws:rds:::cluster-pg:sb-*", "arn:aws:rds:::cluster-snapshot:sb-*", "arn:aws:rds:::db:sb-*", "arn:aws:rds:::pg:sb-*", "arn:aws:rds:::pg:*", "arn:aws:rds:::snapshot:sb-*", "arn:aws:rds:::subgrp:sb-*" ], "Condition": { "ForAnyValue:StringEquals": { "aws:TagKeys": ["AgentName", "ManagedBy", "Vpc", "aws-apn-id", "superblocks:owned"] } } } ] } ``` Allows the lifecycle worker to describe VPC and subnet topology (globally, as required by AWS) and to create and manage security groups scoped to the declared VPC. The `Ec2CreateSecurityGroupVpcScope` statement additionally restricts `CreateSecurityGroup` to the specific VPC resource via `ec2:VpcID`, so the lifecycle worker cannot create security groups in any other VPC. `Ec2CreateTagsOnCreateSecurityGroup` authorizes create-time tagging for `CreateSecurityGroup` and for `AuthorizeSecurityGroupIngress` / `AuthorizeSecurityGroupEgress`, so ownership tags can land on both the security group and its individual rules when they are created. `Ec2DeleteTagsExceptProtectedTags` only Allows removing non-protected tags from managed security groups and rules when `aws:TagKeys` is present; `DenyDeleteProtectedTags` Denies removing the scoping and ownership keys; `DenyDeleteTagsWhenTagKeysAbsent` Denies the delete-all request that omits `Tags` / `aws:TagKeys`. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "Ec2VpcDescribe", "Effect": "Allow", "Action": [ "ec2:DescribeAccountAttributes", "ec2:DescribeAvailabilityZones", "ec2:DescribeNetworkInterfaces", "ec2:DescribeRouteTables", "ec2:DescribeSecurityGroupRules", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeTags", "ec2:DescribeVpcAttribute", "ec2:DescribeVpcs" ], "Resource": "*" }, { "Sid": "Ec2CreateSecurityGroupResource", "Effect": "Allow", "Action": ["ec2:CreateSecurityGroup"], "Resource": "arn:aws:ec2:::security-group/*", "Condition": { "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "Ec2CreateSecurityGroupVpcScope", "Effect": "Allow", "Action": ["ec2:CreateSecurityGroup"], "Resource": "arn:aws:ec2:::vpc/", "Condition": { "StringEquals": { "ec2:VpcID": "" } } }, { "Sid": "Ec2SecurityGroupMutate", "Effect": "Allow", "Action": [ "ec2:AuthorizeSecurityGroupEgress", "ec2:AuthorizeSecurityGroupIngress", "ec2:DeleteSecurityGroup", "ec2:ModifySecurityGroupRules", "ec2:RevokeSecurityGroupEgress", "ec2:RevokeSecurityGroupIngress" ], "Resource": "*", "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" } } }, { "Sid": "Ec2CreateTagsOnCreateSecurityGroup", "Effect": "Allow", "Action": ["ec2:CreateTags"], "Resource": [ "arn:aws:ec2:::security-group/*", "arn:aws:ec2:::security-group-rule/*" ], "Condition": { "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "", "ec2:CreateAction": [ "AuthorizeSecurityGroupEgress", "AuthorizeSecurityGroupIngress", "CreateSecurityGroup" ] }, "StringEqualsIfExists": { "aws:RequestTag/aws-apn-id": "pc:ctelqp437y3cvjkv5rv0z2w4f", "aws:RequestTag/superblocks:owned": "true" } } }, { "Sid": "Ec2CreateTagsOnManagedResources", "Effect": "Allow", "Action": ["ec2:CreateTags"], "Resource": [ "arn:aws:ec2:::security-group/*", "arn:aws:ec2:::security-group-rule/*" ], "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" }, "StringEqualsIfExists": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "", "aws:RequestTag/aws-apn-id": "pc:ctelqp437y3cvjkv5rv0z2w4f", "aws:RequestTag/superblocks:owned": "true" } } }, { "Sid": "Ec2DeleteTagsExceptProtectedTags", "Effect": "Allow", "Action": ["ec2:DeleteTags"], "Resource": [ "arn:aws:ec2:::security-group/*", "arn:aws:ec2:::security-group-rule/*" ], "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" }, "Null": { "aws:TagKeys": "false" }, "ForAllValues:StringNotEquals": { "aws:TagKeys": ["AgentName", "ManagedBy", "Vpc", "aws-apn-id", "superblocks:owned"] } } }, { "Sid": "DenyDeleteProtectedTags", "Effect": "Deny", "Action": ["ec2:DeleteTags"], "Resource": [ "arn:aws:ec2:::security-group/*", "arn:aws:ec2:::security-group-rule/*" ], "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" }, "ForAnyValue:StringEquals": { "aws:TagKeys": ["AgentName", "ManagedBy", "Vpc", "aws-apn-id", "superblocks:owned"] } } }, { "Sid": "DenyDeleteTagsWhenTagKeysAbsent", "Effect": "Deny", "Action": ["ec2:DeleteTags"], "Resource": [ "arn:aws:ec2:::security-group/*", "arn:aws:ec2:::security-group-rule/*" ], "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" }, "Null": { "aws:TagKeys": "true" } } } ] } ``` Allows the lifecycle worker to read RDS-managed master secrets for databases it owns. Secret creation is only permitted via `aws:CalledVia: rds.amazonaws.com`, so the lifecycle worker cannot directly create Secrets Manager secrets; only RDS can, on its behalf. The last statement (`DecryptRdsManagedSecretKmsKey`) handles KMS decryption for the RDS-managed master secret. **Without a customer KMS key** (`rds_secret_kms_key_arn` not set), `Resource` is `"*"` and access is constrained via `kms:ViaService` and `kms:EncryptionContext` as shown below. **With a customer KMS key**, replace `"Resource": "*"` with the specific key ARN. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "CreateRdsManagedMasterSecrets", "Effect": "Allow", "Action": "secretsmanager:CreateSecret", "Resource": [ "arn:aws:secretsmanager:::secret:rds!cluster-*", "arn:aws:secretsmanager:::secret:rds!db-*" ], "Condition": { "ForAnyValue:StringEquals": { "aws:CalledVia": "rds.amazonaws.com" }, "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "TagRdsManagedMasterSecretsViaRds", "Effect": "Allow", "Action": "secretsmanager:TagResource", "Resource": [ "arn:aws:secretsmanager:::secret:rds!cluster-*", "arn:aws:secretsmanager:::secret:rds!db-*" ], "Condition": { "ForAnyValue:StringEquals": { "aws:CalledVia": "rds.amazonaws.com" }, "StringEquals": { "aws:RequestTag/AgentName": "", "aws:RequestTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:RequestTag/Vpc": "" } } }, { "Sid": "DescribeRdsManagedSecretKmsKeyViaRds", "Effect": "Allow", "Action": "kms:DescribeKey", "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "aws:CalledVia": "rds.amazonaws.com" } } }, { "Sid": "ReadTaggedRdsManagedMasterSecrets", "Effect": "Allow", "Action": [ "secretsmanager:DescribeSecret", "secretsmanager:GetSecretValue" ], "Resource": [ "arn:aws:secretsmanager:::secret:rds!cluster-*", "arn:aws:secretsmanager:::secret:rds!db-*" ], "Condition": { "StringEquals": { "aws:ResourceTag/AgentName": "", "aws:ResourceTag/ManagedBy": "superblocks-app-database-lifecycle", "aws:ResourceTag/Vpc": "" } } }, { "Sid": "DecryptRdsManagedSecretKmsKey", "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:DescribeKey" ], "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "secretsmanager..amazonaws.com" }, "StringLike": { "kms:EncryptionContext:SecretARN": [ "arn:aws:secretsmanager:::secret:rds!cluster-*", "arn:aws:secretsmanager:::secret:rds!db-*" ] } } } ] } ``` Allows only the lifecycle worker role for this data plane to assume the connector role. No other principal can assume it. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowOnlyTrustedOpa", "Effect": "Allow", "Action": "sts:AssumeRole", "Principal": { "AWS": [""] } } ] } ``` Grants `rds-db:connect` for each declared data tag, scoped to DB users matching `sbndb__*_runtime` on both RDS instances and Aurora clusters. `` is the first 16 hex characters of `SHA-256(lowercase(tag))` — compute it with `printf '%s' '' | shasum -a 256 | cut -c1-16`. Add or remove statements to match your declared `agent_tags`. The example below shows two data tags (`` and ``). This is the outer bound, not the effective permission on a connection. The data plane assumes this role with a session policy allowing `rds-db:connect` on one specific cluster and DB user, so each connection is authorized for exactly the app it is serving. See [How a connection is authenticated](#how-a-connection-is-authenticated). ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "ConnectTag1", "Effect": "Allow", "Action": "rds-db:connect", "Resource": [ "arn:aws:rds-db:::dbuser:cluster-*/sbndb__*_runtime", "arn:aws:rds-db:::dbuser:db-*/sbndb__*_runtime" ] }, { "Sid": "ConnectTag2", "Effect": "Allow", "Action": "rds-db:connect", "Resource": [ "arn:aws:rds-db:::dbuser:cluster-*/sbndb__*_runtime", "arn:aws:rds-db:::dbuser:db-*/sbndb__*_runtime" ] } ] } ``` Allows the lifecycle worker to manage CloudWatch log groups for Aurora clusters and instances it provisions, and to pass the shared Enhanced Monitoring role to RDS. `logs:DescribeLogGroups` must be scoped to `"Resource": "*"` because AWS does not support resource-level restrictions on describe log group APIs. `logs:UntagResource` is split into an Allow that excludes protected keys (`CloudWatchUntagExceptProtectedTags`) and an explicit Deny (`DenyUntagProtectedTags`), matching the RDS/EC2 protected-tag pattern. `logs:TagResource` is similarly split (`CloudWatchTagResourceWithCanonicalOwnership`) so ownership request-tag values cannot be overwritten. `iam:PassRole` is conditioned on `iam:PassedToService: rds.amazonaws.com`, which is the service principal that RDS uses when calling `CreateDBInstance` — not `monitoring.rds.amazonaws.com`, which is what the monitoring agent assumes later. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "CloudWatchLogGroupsForAppDatabases", "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:DeleteLogGroup", "logs:ListTagsForResource", "logs:PutRetentionPolicy" ], "Resource": [ "arn:aws:logs:::log-group:/aws/rds/cluster/sb-*", "arn:aws:logs:::log-group:/aws/rds/instance/sb-*" ] }, { "Sid": "CloudWatchTagResourceWithCanonicalOwnership", "Effect": "Allow", "Action": "logs:TagResource", "Resource": [ "arn:aws:logs:::log-group:/aws/rds/cluster/sb-*", "arn:aws:logs:::log-group:/aws/rds/instance/sb-*" ], "Condition": { "StringEqualsIfExists": { "aws:RequestTag/aws-apn-id": "pc:ctelqp437y3cvjkv5rv0z2w4f", "aws:RequestTag/superblocks:owned": "true" } } }, { "Sid": "CloudWatchUntagExceptProtectedTags", "Effect": "Allow", "Action": "logs:UntagResource", "Resource": [ "arn:aws:logs:::log-group:/aws/rds/cluster/sb-*", "arn:aws:logs:::log-group:/aws/rds/instance/sb-*" ], "Condition": { "ForAllValues:StringNotEquals": { "aws:TagKeys": ["AgentName", "ManagedBy", "Vpc", "aws-apn-id", "superblocks:owned"] } } }, { "Sid": "DenyUntagProtectedTags", "Effect": "Deny", "Action": "logs:UntagResource", "Resource": [ "arn:aws:logs:::log-group:/aws/rds/cluster/sb-*", "arn:aws:logs:::log-group:/aws/rds/instance/sb-*" ], "Condition": { "ForAnyValue:StringEquals": { "aws:TagKeys": ["AgentName", "ManagedBy", "Vpc", "aws-apn-id", "superblocks:owned"] } } }, { "Sid": "DescribeLogGroupsIsNotResourceScopable", "Effect": "Allow", "Action": "logs:DescribeLogGroups", "Resource": "*" }, { "Sid": "PassEnhancedMonitoringRole", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "", "Condition": { "StringEquals": { "iam:PassedToService": "rds.amazonaws.com" } } } ] } ``` `app_db_prereqs` creates one account-level role named `sb-app-db-enhanced-monitoring` (or `-enhanced-monitoring`) with the following trust policy. Additional regional prerequisite stacks reuse this same role through `existing_monitoring_role_arn`. If your organization must create IAM roles out of band, create the role with this policy and pass its ARN as `existing_monitoring_role_arn` to every prerequisite invocation. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowRdsEnhancedMonitoringForAppDatabases", "Effect": "Allow", "Principal": { "Service": "monitoring.rds.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "ArnLike": { "aws:SourceArn": [ "arn:aws:rds:*::cluster:sb-*", "arn:aws:rds:*::db:sb-*" ] }, "StringEquals": { "aws:SourceAccount": "" } } } ] } ``` The module attaches the AWS-managed `arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole` policy to this role. If you create the role out of band, attach the same policy. The trust policy uses `monitoring.rds.amazonaws.com`, while the lifecycle worker's `iam:PassRole` condition above intentionally uses `rds.amazonaws.com`; these principals serve different parts of the Enhanced Monitoring flow. # Set up Superblocks Database Source: https://docs.superblocks.com/admin/superblocks-on-aws/database-setup Provision Superblocks-managed AWS Aurora PostgreSQL inside your own AWS account using Terraform and your data plane Superblocks Database gives each app its own isolated PostgreSQL database on AWS Aurora PostgreSQL in your AWS account. It lives in your VPC, is encrypted at rest, and authenticates with IAM tokens so there are no passwords to rotate or store. Superblocks manages the database lifecycle; you retain ownership of every AWS resource. Superblocks runs a **shared pool of Aurora PostgreSQL clusters**. Each app that uses Superblocks Database gets its own isolated logical database inside that pool. You can tune isolation and capacity; the defaults keep costs predictable without sacrificing performance. This page is written for the team that owns your AWS account. For the builder-facing view of the same feature, see [Superblocks Database](/admin/superblocks-on-aws/database). ## Prerequisites Superblocks Database runs on Aurora PostgreSQL in your own AWS account, so it requires a [Hybrid](/enterprise/deployment-overview) or [Cloud-Prem](/enterprise/cloud-prem/aws) deployment with a Superblocks [data plane](/enterprise/hybrid-architecture/overview) you operate. It is not available on Superblocks Cloud: every resource lives in your VPC, so there is no multi-tenant equivalent. AWS is the only supported cloud today. Before you start, confirm each of the following: * **A data plane on [ECS Fargate](/enterprise/hybrid-architecture/deployment/aws_ecs_fargate) or [EKS](/enterprise/hybrid-architecture/deployment/kubernetes).** Each data plane covers one AWS account and one AWS region. To run databases in more than one region, deploy one data plane per region. You can also use separate data planes, or separate [data tags](/development-lifecycle/build/data-tags) on the same data plane, to isolate databases by lifecycle stage (for example, staging vs. production). * **Data plane image v1.48.0 or later.** On Fargate, pin `superblocks_agent_image = "ghcr.io/superblocksteam/agent:v1.48.0"`. On EKS, use a chart/`appVersion` that deploys agent `v1.48.0` or newer. * **Terraform or OpenTofu 1.6 or later.** You need this even if you deploy the data plane with Helm and do not otherwise use Terraform, because the IAM roles and the state bucket are only distributed as a Terraform module. OpenTofu is also part of the runtime: your data plane runs `tofu apply` to create and manage databases after setup. * **Permission to create IAM roles, an S3 bucket, and Aurora clusters.** This is a one-time setup operation. See [Reference: Raw IAM policy JSON](/admin/superblocks-on-aws/database-reference#raw-iam-policy-json) if your organization requires policies to be pre-approved. * **A VPC with private subnets in at least two Availability Zones.** * **Enough AWS quota headroom** for Aurora clusters and instances, DB subnet groups, security groups, ENIs, and free IP addresses in your database subnets. The pool grows over time, so plan for more than the first cluster. ## Setup decisions A few values are fixed once a data plane has databases — get them right before you start: * **Agent name** — a stable identifier for this data plane, for example `prod-usw2`. Use at most 15 lowercase alphanumeric characters, unique per AWS account. Becomes the Terraform `agents` map key. * **Data tag names** — the [data tags](/development-lifecycle/build/data-tags) this data plane serves. Must be non-empty and unique across all agents in the module invocation. * **VPC** — where Aurora clusters will be provisioned. See [Reference: Setup decisions](/admin/superblocks-on-aws/database-reference#setup-decisions) for how each of these is used to scope IAM policy, and what changing one later requires. ## One-time setup Setup runs once per data plane: create the AWS prerequisites with Terraform, provision the first Aurora cluster from the admin panel, and confirm builders can use it. After that, Superblocks grows and manages the pool without further setup. ### Step 1: Run the Terraform module Superblocks publishes two submodules as part of the `superblocksteam/superblocks/aws` Terraform registry module. Use a compatible release from version `1.5.2` up to, but not including, `2.0.0` so the prerequisite stack includes the App Database modules, observability IAM resources, and current resource-naming inputs: * `modules/app-db-prereqs`: run by all customers. Creates the lifecycle worker IAM roles, connector IAM roles, shared Enhanced Monitoring role, and shared S3 state bucket. * `modules/app-db`: ECS Fargate only. Takes the prereq outputs plus your database config and renders the data plane runtime configuration as `ecs_env_vars`, ready to inject into the ECS task definition. It also outputs `superblocks_agent_tags` in the form the data plane expects, so the profiles it serves come from the same place as the databases it provisions. If you are updating an existing Terraform deployment, change the constraint and run `terraform init -upgrade` followed by `terraform plan` before applying. This plan covers the prerequisite IAM and S3 resources and the rendered data plane configuration; it does not show changes to Aurora clusters, which live in the lifecycle worker's separate OpenTofu state. Review the prerequisite plan and the observability settings in `physical_module_inputs` (see [Step 1](#step-1-run-the-terraform-module) below) before restarting the data plane. Physical database settings take effect through later lifecycle operations, so verify the resulting configuration on newly provisioned clusters. To cancel before applying, restore the previous version constraint and lock file. Use a single Terraform state bucket for all data planes in a given account and region so subsequent runs are idempotent. For the full inventory of what this run creates, see [Reference: What Superblocks creates in your AWS account](/admin/superblocks-on-aws/database-reference#what-superblocks-creates-in-your-aws-account). ### Values to gather Collect these values first. Replace every `` in the examples with your own values. ``, ``, and `` are the fixed values from [Setup decisions](#setup-decisions) above. | Placeholder | Description | | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `` | [Agent name](/admin/superblocks-on-aws/database-reference#agent-name) for this data plane. Source of truth is the Terraform `agents` map key; also set as Fargate `agent_name` or Helm `superblocks.agentName`, and stamped as the IAM `AgentName` tag. Max 15 characters, lowercase alphanumeric, unique per AWS account. | | `` | OpenTofu state prefix derived from the agent name (default `app-db/`). Copy from `module.app_db_prereqs.agents[""].key_prefix` into Fargate `key_prefix` or Helm `databaseLifecycle.backend.keyPrefix`. See [Agent name](/admin/superblocks-on-aws/database-reference#agent-name). | | `` | [Data tag](/development-lifecycle/build/data-tags) keys this data plane serves (for example in `agent_tags` / Helm `agentTags`) | | `` | AWS region for this data plane | | `` | 12-digit AWS account ID | | `` | VPC where Aurora clusters will be provisioned. The lifecycle worker IAM policy is scoped to this VPC. | | `` | Private subnet IDs for the Aurora subnet group (at least two Availability Zones) | | `` | Security group allowed to reach Aurora on port 5432 (typically your data plane's security group) | Pick the platform your data plane runs on — the steps differ for ECS Fargate and EKS, and you only need to follow one. For Fargate deployments, both modules are run together. The `modules/app-db` outputs (`ecs_env_vars` and `superblocks_agent_tags`) are passed directly into the root `terraform_aws_superblocks` module, which wires them into the ECS task definition. You do not need to inspect the contents of `ecs_env_vars`; it is generated in the expected format. Pin `superblocks_agent_image` to `v1.48.0` in the same module block — see [Prerequisites](#prerequisites). ```mermaid theme={null} sequenceDiagram autonumber participant Admin as Your admin participant TF as Terraform participant AWS as Your AWS account participant ECS as ECS participant DP as Data plane participant SB as Superblocks control plane Admin->>TF: terraform apply: app-db-prereqs plus app-db TF->>AWS: Create lifecycle worker IAM role TF->>AWS: Create connector IAM role TF->>AWS: Create S3 state bucket TF->>ECS: Update task definition: database env vars plus lifecycle worker task role ECS->>DP: Redeploy the data plane automatically DP->>SB: Register capability, engine, and capacity SB-->>Admin: Admin panel shows the registered config as read-only ``` **Step 1a: Add both modules to your Terraform config.** ```hcl theme={null} # Step 1 of 2: IAM roles and S3 state bucket. # Run once per region. All data planes in this region share one S3 state bucket. module "app_db_prereqs" { source = "superblocksteam/superblocks/aws//modules/app-db-prereqs" version = ">= 1.5.2, < 2.0.0" deployment_type = "fargate" region = "" # One entry per data plane in this region. # The map key is : it names the IAM roles, becomes the AgentName # tag on every provisioned resource, and must match Fargate agent_name / # Helm superblocks.agentName. Unique per AWS account (max 15 characters, # lowercase alphanumeric). agents = { "" = { # Data tags namespace the DB users Superblocks provisions for this data plane. # A tag "" creates databases named sbndb__ # with runtime users named sbndb___runtime # ( = first 16 hex of SHA-256 of the lowercased tag). agent_tags = ["", ""] # VPC the lifecycle worker is allowed to provision Aurora into. # The IAM policy is scoped to this VPC. The lifecycle worker cannot create # databases in other VPCs in your account. vpc_id = "" # Optional: OpenTofu state prefix for this data plane inside the shared # S3 bucket. Defaults to app-db/. Must be unique per data plane — # two agents sharing a prefix corrupt each other's OpenTofu state. IAM allows # state access under this prefix only — pass agents[""].key_prefix # into modules/app-db (or Helm keyPrefix) so the runtime uses the same string. # key_prefix = "app-db/" # Optional: attach lifecycle worker policies to an existing ECS task role # instead of creating a new one. Use this for brownfield deployments where # your data plane's ECS task already has a role with permissions to keep. # existing_role_name = "" # Optional: ARN of a customer-managed KMS key used to encrypt the RDS-managed # master secret in Secrets Manager. When omitted, the secret uses the # AWS-managed Secrets Manager key for your account. # rds_secret_kms_key_arn = "arn:aws:kms:::key/" } } # Optional: customer-managed KMS key for the OpenTofu state bucket. # When omitted, the bucket uses AWS-managed encryption (SSE-S3, no extra charge). # When set, the lifecycle worker IAM policy scopes KMS access to this key only. # kms_key_arn = "arn:aws:kms:::key/" # Optional: override the default resource name prefixes (both "sb-app-db"). # IAM roles/policies use iam_name_prefix; the S3 state bucket uses # s3_name_prefix. Set them independently when your organization requires # different naming for IAM vs S3. Max 16 characters each. # iam_name_prefix = "" # s3_name_prefix = "" # Additional inventory tags only. Do not set ManagedBy, superblocks:owned, or # aws-apn-id — app-db-prereqs always enforces those reserved keys. tags = { "" = "" } } # Step 2 of 2: data plane database config. One module call per data plane. # Generates ecs_env_vars in the expected format. module "app_db" { source = "superblocksteam/superblocks/aws//modules/app-db" version = ">= 1.5.2, < 2.0.0" # Must equal the agents map key above (). This is the data plane's # stable identity for the database pool and the AgentName IAM tag. See the # setup decisions above. agent_name = "" # Wired from the agents[""] entry above, so the two cannot diverge. agent_tags = module.app_db_prereqs.agents[""].agent_tags connector_role_arn = module.app_db_prereqs.agents[""].connector_role_arn # All data planes in this region share one bucket. state_bucket_name = module.app_db_prereqs.state_bucket_name region = "" # Namespaces this data plane's OpenTofu state within the shared S3 bucket. # Must match the IAM-granted prefix from app_db_prereqs (default # app-db/). Wire the output — a hand-typed value that differs # fails every state read/write with AccessDenied. key_prefix = module.app_db_prereqs.agents[""].key_prefix # Maximum number of logical databases a single Aurora cluster can hold # before Superblocks queues a task to provision another cluster — the next # app database waits on that provision to finish. pool = { max_databases = 100 } # Physical database configuration for every Aurora cluster # this data plane provisions. physical_module_inputs = { # Enhanced Monitoring is enabled at a low-frequency 60-second interval. # RDS requires the shared monitoring role created by app_db_prereqs. # To opt out, set monitoring_interval = 0 and omit monitoring_role_arn. # Opting out only stops OS metric publication — standard RDS metrics, log # export, and Performance Insights (Standard mode, 7-day retention) stay on # independently. As of v1.5.2 this Fargate helper doesn't expose the inputs # to disable those two; the Helm chart does (see the EKS tab). monitoring_interval = 60 monitoring_role_arn = module.app_db_prereqs.enhanced_monitoring_role_arn # Days to retain automated backups (1 to 35). backup_retention_period = 7 # Delete automated backups when the cluster is destroyed. delete_automated_backups = false # Prevent accidental deletion of the cluster. # Recommended true for always-on workloads. deletion_protection = true # Aurora capacity. Serverless v2 is the default and recommended shape: # capacity scales between min_acu and max_acu with no instance sizing to pick. # instance_count = 2 keeps a second warm instance for immediate failover. # min_acu = 0 pauses an idle cluster (idle-tolerant workloads only) and # requires Aurora PostgreSQL 13.15+, 14.12+, 15.7+, 16.3+, or later. # Aurora provisioned instances are also supported as an alternative to # Serverless v2 if you need fixed instance sizing instead. deployment = { serverless_v2 = { instance_count = 2 max_acu = 32 min_acu = 2 } } # Skip the final snapshot when the cluster is destroyed. # Leave false for always-on workloads to retain a snapshot before deletion. skip_final_snapshot = false # Security groups allowed to reach the database on port 5432, typically # your data plane's security group. source_security_group_ids = [""] # Private subnets for the Aurora subnet group. # Must span at least two Availability Zones. subnet_ids = [ "", "", "", ] # Propagate prereq tags (including enforced ManagedBy, superblocks:owned, # and aws-apn-id). The app-db module also re-merges the ownership pair into # runtime inputs, so those two keys land even if this map is omitted. tags = module.app_db_prereqs.tags # VPC where the Aurora cluster will be created. # Must match the vpc_id declared in the agents map in app_db_prereqs above. vpc_id = "" } } module "terraform_aws_superblocks" { source = "superblocksteam/superblocks/aws" version = ">= 1.5.2, < 2.0.0" vpc_id = "" lb_subnet_ids = ["", ""] ecs_subnet_ids = ["", ""] domain = "" subdomain = "superblocks" superblocks_agent_key = "" # Pin v1.48.0. superblocks_agent_image = "ghcr.io/superblocksteam/agent:v1.48.0" # Comma-separated profile: string, not a list. The app-db # module derives it from its own agent_tags, so wire it from there rather than # writing it out. See the warning below. superblocks_agent_tags = module.app_db.superblocks_agent_tags # Run the ECS task as the lifecycle worker role. This is required and separate # from the env vars below: environment variables cannot change the task role, # so without this the data plane keeps its previous role and every AWS call the # lifecycle worker makes fails with AccessDenied. superblocks_agent_role_arn = module.app_db_prereqs.agents[""].lifecycle_worker_role_arn # Wire the generated database env vars into the ECS task definition. superblocks_agent_environment_variables = module.app_db.ecs_env_vars # Attach the same pre-created task SG you passed as source_security_group_ids # above. Do not reference this module's auto-created ECS SG from app-db — # that is a dependency cycle. ecs_security_group_ids = [""] } ``` **Step 1b: Run `terraform apply`.** The module applies three changes: it creates the prereq resources (IAM roles and S3), renders the data plane runtime config as env vars, and wires them into the ECS task definition along with the lifecycle worker task role. The `agent_tags` in `app_db_prereqs` and the `superblocks_agent_tags` you pass to `terraform_aws_superblocks` must name the same [data tags](/development-lifecycle/build/data-tags). The connector role's `rds-db:connect` permissions are scoped to the DB users derived from `agent_tags`, so if the two diverge, the data plane's IAM token matches no permitted DB user and queries fail. Nothing validates one against the other, which is why the example wires both from module outputs. Writing them by hand means matching two shapes as well as two values: `agent_tags` is a list of bare data tag keys (`["", ""]`), while `superblocks_agent_tags` is one comma-separated string of `profile:` entries (`"profile:,profile:"`). Neither accepts `*`: the control plane routes database work by exact data tag, so `agent_tags` rejects a wildcard and the data plane refuses to start with `profile:*` when Superblocks Database is enabled. **Step 1c: ECS redeploys automatically** when the task definition is updated. Your data plane starts with Superblocks Database enabled and registers its database lifecycle capability with the Superblocks control plane. #### Multiple data planes in the same region To manage multiple data planes in the same region, add one entry per data plane to the `agents` map and one `app_db_*` module call per data plane. All data planes automatically share the same S3 state bucket. Each gets its own isolated IAM roles and its own physical database config. If you need different capacity per data tag set (for example, scale-to-zero on one plane and two warm instances on another), define separate data planes, one per tag set, and give each its own `physical_module_inputs`. Each data plane is also a separate ECS service, so each `app_db_*` module's `ecs_env_vars` output is wired into its own `terraform_aws_superblocks` invocation. ```hcl theme={null} module "app_db_prereqs" { # ...same source, version, deployment_type, and region as above... agents = { "" = { agent_tags = [""] vpc_id = "" } "" = { agent_tags = [""] vpc_id = "" } } } # One app_db module call per data plane. # Always-on shape: two warm instances, never paused. module "app_db" { # ... agent_name = "" agent_tags = module.app_db_prereqs.agents[""].agent_tags connector_role_arn = module.app_db_prereqs.agents[""].connector_role_arn state_bucket_name = module.app_db_prereqs.state_bucket_name key_prefix = module.app_db_prereqs.agents[""].key_prefix pool = { max_databases = 100 } physical_module_inputs = { monitoring_interval = 60 monitoring_role_arn = module.app_db_prereqs.enhanced_monitoring_role_arn deployment = { serverless_v2 = { instance_count = 2 max_acu = 32 min_acu = 2 } } source_security_group_ids = [""] subnet_ids = ["", ""] vpc_id = "" } } # Idle-tolerant shape: one instance that scales to zero after five idle minutes. module "app_db_2" { # ... agent_name = "" agent_tags = module.app_db_prereqs.agents[""].agent_tags connector_role_arn = module.app_db_prereqs.agents[""].connector_role_arn state_bucket_name = module.app_db_prereqs.state_bucket_name key_prefix = module.app_db_prereqs.agents[""].key_prefix pool = { max_databases = 100 } physical_module_inputs = { monitoring_interval = 60 monitoring_role_arn = module.app_db_prereqs.enhanced_monitoring_role_arn deployment = { serverless_v2 = { auto_pause_seconds = 300 instance_count = 1 max_acu = 4 min_acu = 0 } } source_security_group_ids = [""] subnet_ids = ["", ""] vpc_id = "" } } # Each data plane is a separate ECS service. Wire each one's task role and env # vars into its own invocation. Both are per-data-plane. module "terraform_aws_superblocks" { # ... superblocks_agent_image = "ghcr.io/superblocksteam/agent:v1.48.0" superblocks_agent_tags = module.app_db.superblocks_agent_tags superblocks_agent_role_arn = module.app_db_prereqs.agents[""].lifecycle_worker_role_arn superblocks_agent_environment_variables = module.app_db.ecs_env_vars ecs_security_group_ids = [""] } module "terraform_aws_superblocks_2" { # ... superblocks_agent_image = "ghcr.io/superblocksteam/agent:v1.48.0" superblocks_agent_tags = module.app_db_2.superblocks_agent_tags superblocks_agent_role_arn = module.app_db_prereqs.agents[""].lifecycle_worker_role_arn superblocks_agent_environment_variables = module.app_db_2.ecs_env_vars ecs_security_group_ids = [""] } ``` For EKS deployments, the Terraform module handles IAM and S3 only. The database configuration is set separately in your Helm chart under the `databaseLifecycle` block. #### EKS-only prerequisite: OIDC provider ARN In addition to the [values to gather](#values-to-gather) above, EKS needs the cluster's **IAM** OIDC identity provider ARN (``). It is required for IRSA so the data plane pod can assume the lifecycle worker role. Every EKS cluster exposes an OIDC issuer URL. Separately, your AWS account must have an IAM OIDC provider for that issuer — that provider's ARN is what you pass to Terraform. Retrieve it with: ```bash theme={null} CLUSTER_NAME="" REGION="" ISSUER="$(aws eks describe-cluster \ --name "${CLUSTER_NAME}" \ --region "${REGION}" \ --query "cluster.identity.oidc.issuer" \ --output text)" if [[ -z "${ISSUER}" || "${ISSUER}" == "None" ]]; then echo "No OIDC issuer found for cluster ${CLUSTER_NAME} in ${REGION}" >&2 else # Prints the matching IAM OIDC provider ARN, or nothing if none exists yet aws iam list-open-id-connect-providers \ --query "OpenIDConnectProviderList[].Arn" --output text \ | tr '\t' '\n' \ | grep -F "${ISSUER#https://}" fi ``` If that command prints nothing, create the IAM OIDC provider for the cluster before continuing (see [AWS: Create an IAM OIDC provider for your cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)). You can also confirm in the console: copy the **OpenID Connect provider URL** from **EKS** → **Clusters** → your cluster → **Overview** → **Details**, strip the `https://` prefix, then search for that value under **IAM** → **Identity providers**. Open the matching provider — its ARN is at the top of the page. ```mermaid theme={null} sequenceDiagram autonumber participant Admin as Your admin participant TF as Terraform participant AWS as Your AWS account participant Helm as Helm participant DP as Data plane participant SB as Superblocks control plane Admin->>TF: terraform apply: app-db-prereqs TF->>AWS: Create lifecycle worker IAM role TF->>AWS: Create connector IAM role TF->>AWS: Create S3 state bucket TF-->>Admin: Output role ARNs and bucket name Admin->>Helm: Add role ARNs, bucket, and db config to values.yaml Admin->>Helm: helm upgrade Helm->>DP: Restart the data plane with Superblocks Database enabled DP->>SB: Register capability, engine, and capacity SB-->>Admin: Admin panel shows the registered config as read-only ``` **Step 1a: Run the prereqs module and apply.** ```hcl theme={null} module "app_db_prereqs" { source = "superblocksteam/superblocks/aws//modules/app-db-prereqs" version = ">= 1.5.2, < 2.0.0" deployment_type = "eks" region = "" # One entry per data plane in this region. # The map key is : it names the IAM roles, becomes the AgentName # tag on every provisioned resource, and must match Fargate agent_name / # Helm superblocks.agentName. Unique per AWS account (max 15 characters, # lowercase alphanumeric). agents = { "" = { # Data tags namespace the DB users Superblocks provisions for this data plane. # A tag "" creates databases named sbndb__ # with runtime users named sbndb___runtime # ( = first 16 hex of SHA-256 of the lowercased tag). agent_tags = ["", ""] # VPC the lifecycle worker is allowed to provision Aurora into. # The IAM policy is scoped to this VPC. The lifecycle worker cannot create # databases in other VPCs in your account. vpc_id = "" # Optional: OpenTofu state prefix for this data plane inside the shared # S3 bucket. Defaults to app-db/. Must be unique per data plane — # two agents sharing a prefix corrupt each other's OpenTofu state. IAM allows # state access under this prefix only — pass agents[""].key_prefix # into Helm databaseLifecycle.backend.keyPrefix so the runtime uses the same string. # key_prefix = "app-db/" # ARN of the EKS cluster's IAM OIDC provider. Required for EKS (IRSA). # Look up with: aws iam list-open-id-connect-providers (filter by the # issuer URL with https:// stripped). See "EKS-only prerequisite: # OIDC provider ARN" above. oidc_provider_arn = "" # Kubernetes namespace and service account name of the data plane pod. # Used to scope the OIDC trust policy condition to the specific service account # (system:serviceaccount::). # Defaults match the standard Superblocks Helm chart values. Only override if you deviate. # namespace = "superblocks" # service_account_name = "superblocks-agent" # Optional: attach lifecycle worker policies to an existing IRSA role # instead of creating a new one. Use this for brownfield deployments where # your data plane pod already has an IRSA-annotated role from a prior Helm install. # existing_role_name = "" # Optional: ARN of a customer-managed KMS key used to encrypt the RDS-managed # master secret in Secrets Manager. When omitted, the secret uses the # AWS-managed Secrets Manager key for your account. # rds_secret_kms_key_arn = "arn:aws:kms:::key/" } } # Optional: customer-managed KMS key for the OpenTofu state bucket. # When omitted, the bucket uses AWS-managed encryption (SSE-S3, no extra charge). # When set, the lifecycle worker IAM policy scopes KMS access to this key only. # kms_key_arn = "arn:aws:kms:::key/" # Optional: override the default resource name prefixes (both "sb-app-db"). # IAM roles/policies use iam_name_prefix; the S3 state bucket uses # s3_name_prefix. Set them independently when your organization requires # different naming for IAM vs S3. Max 16 characters each. # iam_name_prefix = "" # s3_name_prefix = "" # Additional inventory tags only. Do not set ManagedBy, superblocks:owned, or # aws-apn-id — app-db-prereqs always enforces those reserved keys. tags = { "" = "" } } ``` **Step 1b: Wire the outputs into your Helm values.** After `terraform apply`, add the module outputs and your database config to your Helm values. The settings span four top-level sections, not just `databaseLifecycle`. The two IAM roles in particular are wired through the sections that already own identity in the chart: | What | Where it goes | Why there | | -------------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Agent name (``) | `superblocks.agentName` | Must equal the [agent name](/admin/superblocks-on-aws/database-reference#agent-name) used as the Terraform `agents` map key | | OpenTofu state prefix (``) | `databaseLifecycle.backend.keyPrefix` | Must equal `module.app_db_prereqs.agents[""].key_prefix`, as described under [Agent name](/admin/superblocks-on-aws/database-reference#agent-name) | | Lifecycle worker role | `serviceAccount.annotations` | EKS grants pod identity through the IRSA annotation, so the role reaches the pod the same way any other AWS role does | | Connector role | `postgres.appDbConnectorRoleArn` | It is a query-time database credential, and `postgres` owns the data plane's PostgreSQL connection settings | | Enhanced Monitoring role | `databaseLifecycle.physicalModuleInputs.monitoring_role_arn` | RDS requires this role to publish operating-system metrics at the configured interval | | Data tags | `superblocks.agentTags` | Source of truth for which data tags accept database work | | Ownership / APN tags | `databaseLifecycle.physicalModuleTags` | Required. Set `superblocks:owned: "true"` and `aws-apn-id: "pc:ctelqp437y3cvjkv5rv0z2w4f"` (fixed Superblocks Partner Network ID, not per-account). The Helm chart does not inject these. Do not set `ManagedBy`, `AgentName`, or `Vpc` — the lifecycle worker stamps those | | Packaged modules | `databaseLifecycle.modules` | Set logical and physical sources to the modules packaged in the data plane image (`./modules/...`). Override only to run a fork or a custom module | | Everything else | `databaseLifecycle` | Feature-specific configuration | Reuse the same [agent name](/admin/superblocks-on-aws/database-reference#agent-name) you set as the `agents` map key, and copy the state prefix from the Terraform output. Helm cannot detect a mismatch, and IAM fails the work later: a different `superblocks.agentName` lets the pod assume the lifecycle worker role but fails every tagged create and mutate with `AccessDenied`, and a different `keyPrefix` fails every OpenTofu state read and write with `AccessDenied`. To use a prefix other than the default, set `agents[""].key_prefix` in `app_db_prereqs` and copy the new output — do not type a value such as `app-db/prod` only into Helm. ```yaml theme={null} superblocks: # Must equal the agents map key in app_db_prereqs. # Also becomes the AgentName tag on every Aurora resource this data plane creates. # Required when Superblocks Database is enabled. agentName: # Comma-separated string, each data tag prefixed with profile:. # Must cover the same data tags as agent_tags above. See the warning below. agentTags: profile:,profile: serviceAccount: annotations: # Lifecycle worker role, assumed by the data plane pod through IRSA. # From: module.app_db_prereqs.agents[""].lifecycle_worker_role_arn eks.amazonaws.com/role-arn: "" postgres: # Connector role, used at query time to authenticate to app databases with # RDS IAM tokens. # From: module.app_db_prereqs.agents[""].connector_role_arn appDbConnectorRoleArn: "" # The data plane refuses to authenticate as any IAM role outside this list. # It must cover appDbConnectorRoleArn above, or the chart rejects the upgrade. iamAllowedRoleArnPrefixes: - "" databaseLifecycle: enabled: true # Use the database modules packaged in the data plane image. # Override only to run a fork or a custom module. modules: logical: source: ./modules/postgres-managed-database physical: source: ./modules/aws-aurora-managed-cluster # OpenTofu state. The bucket is shared across every data plane in this account # and region; keyPrefix namespaces this data plane's state inside it and must # be unique per data plane. Copy the IAM-granted prefix from # module.app_db_prereqs.agents[""].key_prefix (default # app-db/). A hand-typed value that differs fails every state # read/write with AccessDenied. backend: stateBackend: s3 # From: module.app_db_prereqs.state_bucket_name bucket: "" region: "" # From: module.app_db_prereqs.agents[""].key_prefix keyPrefix: "" useLockfile: true # Secrets Manager ARNs the data plane may read, used to fetch the AWS-managed # Aurora master credential during provisioning. Scope this to RDS-managed # secrets in your account and region. An empty list denies resolution, which # makes every provision fail. Use the rds!db- prefix instead for standalone RDS. allowedRefPrefixes: - arn:aws:secretsmanager:::secret:rds!cluster- # Maximum number of logical databases a single Aurora cluster can hold # before Superblocks queues a task to provision another cluster — the next # app database waits on that provision to finish. pool: maxDatabases: 100 # Required ownership / APN tags. The Helm chart does not inject these; IAM # create on runtime Aurora fails with AccessDenied unless they are present. # aws-apn-id is Superblocks' AWS Partner Network ID — copy the literal # below verbatim; it is not per-account. Do not set ManagedBy, AgentName, # or Vpc — the lifecycle worker stamps those. The chart merges # physicalModuleTags over physicalModuleInputs.tags when both are present. # Additional inventory tags (cost center, team) can be mixed in. physicalModuleTags: aws-apn-id: "pc:ctelqp437y3cvjkv5rv0z2w4f" superblocks:owned: "true" # : "" # Physical database configuration for every Aurora cluster # this data plane provisions. physicalModuleInputs: # Enhanced Monitoring at a low-frequency 60-second interval. # From: module.app_db_prereqs.enhanced_monitoring_role_arn # To opt out, set monitoring_interval: 0 and omit monitoring_role_arn. # Opting out only stops OS metric publication — standard RDS metrics, log # export, and Performance Insights (Standard mode, 7-day retention) stay on # independently. Disable those two here with enabled_cloudwatch_logs_exports: [] # and performance_insights_enabled: false (Fargate can't, as of v1.5.2). monitoring_interval: 60 monitoring_role_arn: "" # Days to retain automated backups (1 to 35). backup_retention_period: 7 # Delete automated backups when the cluster is destroyed. delete_automated_backups: false # Prevent accidental deletion of the cluster. # Recommended true for always-on workloads. deletion_protection: true # Aurora capacity. Serverless v2 is the module default and the recommended # shape: capacity scales between min_acu and max_acu with no instance sizing # to pick. instance_count 2 keeps a second warm instance for immediate # failover. Spelled out here because these values determine what the pool # costs as it grows, so choose them deliberately. min_acu: 0 pauses an idle # cluster (idle-tolerant workloads only) and requires Aurora PostgreSQL # 13.15+, 14.12+, 15.7+, 16.3+, or later. Aurora provisioned instances are # also supported as an alternative if you need fixed instance sizing. deployment: serverless_v2: instance_count: 2 max_acu: 32 min_acu: 2 # Skip the final snapshot when the cluster is destroyed. # Leave false for always-on workloads to retain a snapshot before deletion. skip_final_snapshot: false # Security groups allowed to reach the database on port 5432, typically # your data plane's security group. source_security_group_ids: - "" # Private subnets for the Aurora subnet group. # Must span at least two Availability Zones. subnet_ids: - "" - "" - "" # VPC where the Aurora cluster will be created. # Must match the vpc_id declared in the agents map in app_db_prereqs above. vpc_id: "" ``` Values not shown keep their chart defaults, which are the recommended settings: * **TLS** uses `verify-full` against the AWS trust bundle packaged in the data plane image. The chart refuses to enable Superblocks Database with any weaker mode. * **The OpenTofu working directory and binary path** are fixed properties of that image. The chart rejects attempts to override either. * **The resource types the lifecycle worker may create** default to exactly what the database modules it ships with declare. Set `allowedResourceTypes` only to run a fork or a custom module. A non-empty list replaces the default outright rather than adding to it. The `agent_tags` in `app_db_prereqs` and the `agentTags` in your Helm values must name the same [data tags](/development-lifecycle/build/data-tags). The connector role's `rds-db:connect` permissions are scoped to the DB users derived from `agent_tags`, so if the two diverge, the data plane's IAM token matches no permitted DB user and queries fail. Nothing validates one against the other. The two inputs also take different shapes: `agent_tags` is a list of bare data tag keys (`["", ""]`), while `agentTags` is one comma-separated string of `profile:` entries (`"profile:,profile:"`). Neither accepts `*`: the control plane routes database work by exact data tag, so `agent_tags` rejects a wildcard and the chart refuses to render `profile:*` when Superblocks Database is enabled. **Step 1c: Upgrade your Helm chart.** ```bash theme={null} helm upgrade superblocks-agent superblocksteam/superblocks-agent \ -f values.yaml \ --namespace superblocks ``` Your data plane restarts with Superblocks Database enabled and registers its database lifecycle capability with the Superblocks control plane. #### Multiple data planes in the same region For multiple data planes in the same region (whether in the same EKS cluster or separate clusters), add one entry per data plane to the `agents` map. Each gets its own lifecycle worker role and connector role, scoped to its own OIDC provider and VPC. They all share the S3 state bucket automatically. ```hcl theme={null} module "app_db_prereqs" { # ...same source, version, deployment_type, and region as above... agents = { "" = { agent_tags = [""] vpc_id = "" oidc_provider_arn = "" } "" = { agent_tags = [""] vpc_id = "" oidc_provider_arn = "" } } } ``` Each data plane then gets its own Helm values file referencing its own entry in the `agents` output. Use `module.app_db_prereqs.agents[""]` for one data plane and `module.app_db_prereqs.agents[""]` for the other. The `state_bucket_name` output is shared and used by both. #### Additional AWS regions Use a separate `app_db_prereqs` invocation with an AWS provider alias for each additional region. Each region gets its own S3 state bucket, but the Enhanced Monitoring IAM role is account-global. Designate the first region as the role's durable home and pass its output to every additional region: ```hcl theme={null} provider "aws" { alias = "secondary" region = "" } module "app_db_prereqs_secondary" { source = "superblocksteam/superblocks/aws//modules/app-db-prereqs" version = ">= 1.5.2, < 2.0.0" providers = { aws = aws.secondary } deployment_type = "" region = "" existing_monitoring_role_arn = module.app_db_prereqs.enhanced_monitoring_role_arn agents = { # Configure the data planes in this region as shown above. } } ``` The example above assumes both regional module calls share one Terraform root and state. If each region uses separate state, pass the owning stack's output through `terraform_remote_state` or supply the concrete ARN (`arn:aws:iam:::role/-enhanced-monitoring`) as `existing_monitoring_role_arn`. The secondary prerequisite stack re-exports the supplied role through its own `enhanced_monitoring_role_arn` output. Use `module.app_db_prereqs_secondary.enhanced_monitoring_role_arn` as `monitoring_role_arn` in that region's Fargate `physical_module_inputs` or EKS `physicalModuleInputs`, exactly as in the primary-region examples. The first region's prerequisite stack owns a cross-region dependency. Do not destroy that stack while any other region uses its Enhanced Monitoring role. Do not add `existing_monitoring_role_arn` later to the stack that created the role without first moving every consumer to another role; Terraform would destroy the role that stack currently owns. If that role was deleted or changed accidentally, first check for `-enhanced-monitoring` in IAM. Restore the original owning prerequisite stack and run `terraform apply` to recreate its trust policy and managed-policy attachment. Because the recreated role has the same ARN, existing regional consumers can resume using it. To move ownership deliberately, create a replacement role, update every regional prerequisite stack and physical database input to the replacement ARN, apply those changes, and only then remove the old role. ### Step 2: Provision your database from the admin panel Once the data plane is running with Superblocks Database enabled, return to the data plane setup wizard, or open the Superblocks admin panel and navigate to **Databases**. You will see the database configuration registered by your data plane, including the engine, capacity settings, and data tags pulled from its running configuration. These are read-only: they reflect what you configured in Terraform or Helm. Click **Provision**. Superblocks dispatches the request to your data plane, which runs `tofu apply` in your AWS account. You do not re-enter any configuration; it is already in the data plane. ```mermaid theme={null} sequenceDiagram autonumber participant Admin as Admin panel participant SB as Superblocks control plane participant DP as Data plane lifecycle worker participant AWS as Your AWS account Admin->>SB: Click Provision SB->>SB: Deduplicate: one provisioning request per deployment DP->>SB: Claim the provisioning request SB->>DP: Dispatch the provisioning request DP->>AWS: tofu init plus tofu apply Note over AWS: Aurora cluster
DB subnet group
Security group and rules
tagged AgentName, ManagedBy, Vpc, superblocks:owned, and aws-apn-id AWS-->>DP: Cluster ready DP->>SB: Terminal callback: success or failure with error detail SB-->>Admin: Admin panel reflects the result ``` Provisioning an Aurora cluster typically takes 5 to 15 minutes. The admin panel shows live status and updates automatically, so you do not need to keep the browser open. **If two admins click Provision at the same time**, only one request proceeds. The second admin sees that provisioning is already in progress and when it started, and can follow the same live status. **When provisioning completes**, the data plane sends a confirmation to the Superblocks control plane and the panel shows a success state. If provisioning fails, you see the error detail and a retry option. Failures are surfaced here, not to end users. ### Step 3: Ready Once the panel shows a success state, your builders can create apps backed by Superblocks Database immediately. There is no cold-start wait, because the database pool is already running. ```mermaid theme={null} sequenceDiagram autonumber participant Builder participant SB as Superblocks control plane participant DP as Data plane lifecycle worker participant Pool as Shared Aurora cluster Builder->>SB: Create an app backed by Superblocks Database SB->>Pool: Check capacity in the shared pool alt Capacity available SB->>DP: Dispatch: create logical database DP->>Pool: tofu apply: create PostgreSQL database and role DP->>SB: Ready callback SB-->>Builder: App integration ready in seconds else Pool full SB->>DP: Dispatch: provision a new Aurora cluster first DP->>SB: New cluster registered in the pool SB->>DP: Dispatch: create logical database DP->>Pool: tofu apply DP->>SB: Ready callback SB-->>Builder: App integration ready in 5 to 15 minutes end ``` From this point: * **Builders** can create apps backed by Superblocks Database without any infrastructure wait. Superblocks provisions an isolated logical database inside the shared pool on demand. * **Deploys are gated.** Superblocks blocks a deploy if the deploy-time database or its required SQL migrations are not ready. ### Step 4: Verify observability Open the newly provisioned cluster in the AWS RDS console and confirm that its settings match the options you selected: * **CloudWatch Logs exports** includes `postgresql`, with a corresponding `/aws/rds/cluster//postgresql` log group retained for 30 days. EKS deployments may show no export if you explicitly disabled it; Fargate deployments must show it. * **Database Insights** is in Standard mode, with Performance Insights enabled and retained for 7 days. EKS deployments may show it disabled if you explicitly opted out; Fargate deployments must show it enabled. * **Enhanced Monitoring** is enabled at a 60-second interval, unless you disabled it. Seeing a signal you opted out of listed as disabled is expected, not a setup failure. This step only confirms that the signals you asked for are available; what the enabled signals actually record is covered under [Reference: Observability defaults](/admin/superblocks-on-aws/database-reference#observability-defaults), and dashboards, alarms, and incident response remain your organization's responsibility. ## You own the AWS resources Every resource lives in your account, and AWS bills you directly for it. The Superblocks defaults balance cost and performance for most customers. **Pool growth is automatic.** As each cluster reaches its `max_databases` limit, another is added to the pool, so your spend grows with usage without another `terraform apply`. The capacity and pool settings from [Step 1](#step-1-run-the-terraform-module) (ACU range, `instance_count`, and `max_databases`) determine what that growth costs. The admin **Databases** page shows current pool state and capacity. ### Protect the OpenTofu state bucket The state bucket is how Superblocks tracks what it created so it can later modify, resize, or retire those resources. If the state is lost, Superblocks can no longer manage the existing databases and recovery is a manual exercise. * Leave versioning enabled and leave the non-current version expiration alone. * Do not rename, move, or re-encrypt the bucket, and do not manage it with another tool. * Do not add lifecycle rules that expire current object versions. ### Do not manage the tagged resources by hand Editing or deleting the tagged `sb-*` clusters, subnet groups, or security groups directly in the AWS console creates drift that the lifecycle worker will attempt to reconcile on its next run. Route changes through your Terraform or Helm configuration instead. ### Keep the data plane current The data plane image contains the lifecycle worker and the database modules it applies. Fixes, new engine options, and configuration changes ship with data plane releases, so a data plane that is not upgraded falls behind on both. See [Upgrading the data plane](/enterprise/hybrid-architecture/manage/upgrade). ### What Superblocks does, and what stays yours Superblocks creates, configures, scales, and retires the Aurora clusters and the per-app logical databases, and runs your applications' SQL migrations. Superblocks does **not**: * **Patch or upgrade the database engine.** AWS applies engine patches during the maintenance window you configure. Because applications share a cluster, a patch or failover affects every application on that cluster. Running a second instance (`instance_count = 2`) reduces the impact but does not remove it. * **Restore your data.** Automated backups are configured from your `backup_retention_period`, but performing a point-in-time restore or a snapshot restore is an operation you run in AWS. * **Tune PostgreSQL for your workload**, or manage database grants beyond the roles it creates for each application. * **Monitor the database on your behalf.** Superblocks enables the observability signals described above, but the metrics and logs stay in your AWS account. Your organization owns access, dashboards, alarms, and incident response. # Superblocks File Store Source: https://docs.superblocks.com/admin/superblocks-on-aws/file-store Give every app its own managed file storage on your infrastructure ## Overview Apps need to handle files. Builders ask Clark to "let users upload receipts," "attach documents to a request," or "store generated PDF reports". Every one of those features needs somewhere to put the files. Without a native file store, this creates the same problem as databases: either IT provisions and manages storage buckets manually for every app, or builders use external services that move files outside your network. Superblocks File Store solves both problems: * **Every app gets its own file storage automatically.** Builders describe the feature they want, and Clark provisions an isolated storage bucket on your infrastructure. No tickets, no manual setup, no cloud console required. * **Files never leave your network.** Storage is provisioned on your own Amazon S3 backend inside your environment. Superblocks orchestrates the flow but your files stay on your infrastructure. * **Each app is fully isolated.** Every app gets its own separate bucket, so there is no risk of cross-app file access. * **Dev and production are separated by default.** Just like [Superblocks Database](/admin/superblocks-on-aws/database), every app gets separate development and production storage. Test files never reach production, and the builder does not need to configure it. Each app's file storage is a dedicated bucket on **Amazon S3** in your account. When a builder asks Clark for a feature that involves files, the platform provisions storage on S3 automatically — the builder never knows the underlying storage system exists. ## How it works ### 1. Admin configures S3 In **Organization Settings**, administrators connect their Amazon S3 backend and set it as the default for all new apps. This is a one-time setup. ### 2. Clark provisions storage per app When a builder asks Clark to handle files — for example, "let users upload receipts" or "store generated reports" — Clark automatically: * Provisions an isolated storage bucket for that app * Configures upload and download APIs * Wires up the app UI to the storage backend ### 3. Files stay on your infrastructure All uploaded files are stored directly in your cloud storage backend. Superblocks orchestrates the upload and download flow, but the files themselves live in your environment, subject to your existing access controls, encryption policies, and compliance requirements. ## What builders experience From the builder's perspective, file storage is invisible. They prompt Clark to add a feature that handles files, and Clark provisions the storage, builds the APIs, and connects the UI. Builders do not need to know which storage backend is in use or how to configure it. # Inference on Amazon Bedrock Source: https://docs.superblocks.com/admin/superblocks-on-aws/inference Run Clark AI inference through Amazon Bedrock so every prompt executes in your AWS account ## Overview Inference through customer's Amazon Bedrock is available on [Cloud-Prem](/enterprise/cloud-prem/aws) deployments only. By default, Clark AI runs inference through models hosted in the Superblocks Cloud. Administrators can instead point Clark at **Amazon Bedrock**, so every prompt runs on models in your own AWS account. Once configured, every prompt that every builder sends to Clark runs inference through Bedrock. Tokens burn down your existing AWS commitment and reduce Clark GAU usage. Builders do not need to configure anything; they use Clark exactly as before. ## How it works ### 1. Admin configures Bedrock In **Organization Settings**, an administrator connects Amazon Bedrock and supplies the necessary credentials and the models and regions Clark should use. ### 2. All builders inherit the configuration Once saved, every builder in the organization automatically runs inference through Bedrock for all Clark interactions. There is no per-user or per-app setup required. ### 3. Inference burns down your commitment and reduces Clark GAU usage Every prompt a builder sends — whether exploring a database schema, generating a plan, or writing code — runs inference on Bedrock. Token consumption counts toward your existing AWS commitment and reduces Clark GAU usage. ## What this means for your organization * **Burn down your AWS commitment**: Inference runs on Bedrock, contributing to your AWS commitment and reducing Clark GAU consumption * **Inference runs in your network**: All model inference executes within your AWS account * **No builder friction**: Builders use Clark identically regardless of the underlying provider # Adding context Source: https://docs.superblocks.com/building-with-clark/adding-context Target elements, tag APIs, and upload files to focus your prompts The more context you can provide Clark on where / what to build, the better. For example, to iterate on a specific feature after an initial generation, you can **target** or **tag** the relevant components so Clark knows exactly what parts of the application to focus on (e.g., sidebar, specific div, backend API). Similarly, in addition to prompting with text alone, **uploading files** (e.g. screenshots, CSVs) is an effective way to provide Clark with more information on the requirements at any point in a chat. ## Targeting frontend elements To focus Clark on any specific parts of the UI, select the **Target** icon in the chat or use keyboard shortcuts (hold `⌘` on Mac or `Ctrl` on PC).
Enter target mode with Clark
After entering target mode, select any element on the canvas to add it to the chat context before submitting a new prompt. Targeted elements are highlighted in purple and added to the chat context. Selecting components in target mode ## Tagging backend APIs Similar to integrations, you can focus Clark on specific APIs by @mentioning them in chat. Tag API in chat with @ ## Uploading files To add more detail to your prompts, upload files like images, JSON, CSVs, and more. For example, include a screenshot or wireframe to convey layout, hierarchy, and component states. You can attach files from the Clark chat in the editor and from the Clark prompt on the homepage.
Attach files in chat
### File size limits * **Images**: up to **50 MB** raw. Large images are automatically resized so the longest edge is at most **1568 pixels** before Clark receives them. * **Text files** (for example JSON, CSV, Markdown): up to **1 MB**. # Backend APIs Source: https://docs.superblocks.com/building-with-clark/backend-apis Superblocks APIs power the backend of your applications. APIs can call [integrations](/integrations/overview) (databases, REST or GraphQL APIs, SaaS platforms) and run custom TypeScript logic. ## API panel The API panel shows execution details for each API (docked to bottom of the editor by default). Backend API There you can view a list of API calls and drill into individual API calls. Each API call includes a trace view to view timing and inputs / outputs of the API and individual integration calls. Backend API integration call ## API source code Under the hood, every API is a TypeScript file that uses the Superblocks API SDK to call your integrations. Click **\<> View code** on any API to inspect the source code. For editing this code directly, see [developing apps in code](/building-with-clark/developing-apps-in-code). Backend API source code # Builder MCP Source: https://docs.superblocks.com/building-with-clark/builder-mcp Build, edit, and publish governed Superblocks apps from where you already work: Claude, Slack, ChatGPT, and Teams