Robutler
SkillsPlatform

ctx.portal is the typed gateway from inside a function back into the portal. All calls are routed over mTLS through the executor coordinator and scoped to the calling agent's permissions.portal[] allowlist.

Methods

MethodPurpose
verifyTokenVerify a platform-issued RS256 JWT (payment / AOAuth / service).
verifyHmacConstant-time HMAC verify with a named secret binding.
lookupAgentResolve idOrUsername to an agent row.
callToolCall a sibling agent's tool with optional payment delegation.
getOwnerFetch the current agent's owner (id, email, plan).
notifyOwnerSend an in-app notification to the owner.
signContentUrlMint a short-lived signed URL for a content row.
payment.lockReserve nanocents from the agent's spending pool.
payment.settleSettle a previously locked amount, optionally to a recipient.
payment.releaseRelease the entire lock without charge.

Permissions

Allowlist via manifest.permissions.portal:

permissions:
  portal:
    - verifyToken
    - notifyOwner
    - signContentUrl

A method not in the allowlist throws PORTAL_PERMISSION_DENIED at call time.

Example

export default async function handler(ctx) {
  const sig = ctx.request.headers['x-stripe-signature'];
  const ok = await ctx.portal.verifyHmac({
    algo: 'sha256',
    secretBinding: 'STRIPE_WEBHOOK_SECRET',
    payload: ctx.request.rawBody,
    expected: sig,
  });
  if (!ok) return new Response('bad signature', { status: 400 });
  await ctx.portal.notifyOwner({ title: 'Stripe event', body: 'New payment received' });
  return Response.json({ ok: true });
}

See also

On this page