19Docs

App management

Your backend can create and manage other Bounded apps through ctx.apps. Use it for separate customer workspaces, temporary previews, or an app that builds other apps.

Give a Function permission

Add apps: true to the Function declaration in policy.json. Keep its auth rule restricted to the people who should manage apps.

policy.json
{
  "constants": { "FUNCTION_OWNER": "replace-with-your-bounded-user-id" },
  "functions": {
    "createWorkspace": {
      "entry": "functions/createWorkspace.ts",
      "auth": "@user.id == @const.FUNCTION_OWNER",
      "apps": true,
      "timeout": 30
    }
  }
}

Replace the owner constant with the ID from bounded whoami --json. The platform reads this permission from the deployed policy. A caller cannot grant it through Function arguments.

Create a child app

A managed child is an app under the calling app's control. Choose its protocol and a spending ceiling when you create it.

functions/createWorkspace.ts
export default async function (args, ctx) {
  if (typeof args.workspaceId !== "string" || !args.workspaceId.trim()) {
    throw new Error("workspaceId is required");
  }
  const result = await ctx.apps.create({
    name: "Customer workspace",
    protocol: "realtime_offchain",
    ownership: "managed-child",
    spendCeilingMicroUsd: 1_000_000,
    idempotencyKey: "workspace:" + args.workspaceId,
  });
  if (!result.ok) return result;
  return { appId: result.targetAppId };
}

The example sets a ceiling of 1,000,000 micro-USD, which equals $1. A ceiling limits spending. It does not add credit.

Use one idempotencyKey for each intended creation. Reuse that key when you retry the same request. Check ok before you use targetAppId.

Creation gives you an app identity. Install a release or use ctx.build to add the app's policy, code, and frontend.

What ctx.apps can do

TaskMethods
Find controlled apps and inspect their statelist, inspect
Read or write target app dataget, set, setMany
Call a target app Functioninvoke
Set a spending ceiling or pass allowed secretssetSpendCeiling, setSecrets
Copy or install a releasecloneRelease, installRelease
Manage a preview or its addressextendPreview, claimSlug, retire
Authorize and attach a user-owned appauthorizeUserApp, attachUserApp, authorizeControl
Delete an eligible controlled appdelete

Writes through set and setMany still pass the target app's rules and invariants.setMany accepts up to 100 documents in one atomic write.

A user-owned app needs explicit user authorization before another app can attach or control it. Knowing an app ID does not grant access.

App management and app builds

ctx.apps manages app identities, releases, permissions, and lifecycle.ctx.build starts and inspects code builds. A Function needs a separate build declaration for those operations.

Cross-app builds also need the apps permission and control of the target. See Functions for the other backend services.

Handle failures and retries

App operations can return ok: false with a reason. Keep the result and operation ID when a request needs reconciliation.

If invoke reports reconciling, retry the same operation with the same key. Do not create a new key to repeat a potentially completed action.