XY Logo
Developer hub

Credentials and MFA

Give workflows a reference, never a password.

A Marketplace API key authenticates your integration to XY. A runtime credential authenticates an XY browser workflow to a third-party portal. They have separate scopes, lifecycles, and exposure rules.

Two credential types

Control-plane auth and portal auth stay separate.

Confusing the partner key with the portal login is both a security risk and a broken workflow design.

Marketplace API key

Your service → XY

  • Identifies one organization and environment.
  • Scopes REST and MCP operations.
  • Created in Organization settings and shown once.
  • Never supplied as workflow input or browser memory.

Runtime credential

XY browser → portal

  • Vault-backed username/password and optional factors.
  • Referenced by a stable organization-owned credential ID.
  • Resolved only while authoring or executing the browser activity.
  • Secret values are never returned by credential read routes.

Create

Store the portal login, then discard the write body.

The write request is the one trusted transfer of the portal secret. The response is safe metadata and a stable credential ID.
Create a secure credential reference
# Build this body from a protected secret source; do not paste it into shell history.
curl --fail-with-body --request POST \
  --header "Authorization: Bearer ${XY_API_KEY}" \
  --header "Content-Type: application/json" \
  "${XY_API_BASE}/credentials" \
  --data @credential.json

# credential.json
{
  "domain": "portal.example.com",
  "site_name": "Example operations portal",
  "username": "workflow-user",
  "password": "read-from-your-secret-manager",
  "login_url": "https://portal.example.com/login",
  "totp": "optional-base32-seed",
  "pin": "optional-static-pin",
  "phone_number": "+12025550123",
  "notes": "optional private vault notes"
}

Use credentials:write for create, rotate, and revoke, andcredentials:read for safe metadata. Keep write access out of ordinary Planner and analytics keys.

Bind

The ID crosses the workflow boundary; the secret does not.

Planner accepts the credential reference in structured context. Secret-shaped fields are recursively rejected from the Planner request.
Start Planner with a credential reference
curl --fail-with-body --request POST \
  --header "Authorization: Bearer ${XY_API_KEY}" \
  --header "Idempotency-Key: portal-flow-v1" \
  --header "Content-Type: application/json" \
  "${XY_API_BASE}/planner/builds" \
  --data '{
    "request": "Sign in and collect the open records.",
    "context": {
      "portal_url": "https://portal.example.com/open-records",
      "credential_id": "cred_REPLACE"
    }
  }'

Validate

Planner verifies that the reference is active and belongs to the key's organization.

Bind

The canonical vault domain is derived by XY. A conflicting caller-supplied domain is rejected.

Resolve

The runtime loads the credential only for the bound browser authoring or execution session.

Runtime memory

Each authentication factor has a specific job.

The browser SDK receives a small, conventional set of ephemeral memory values. Generated activity code reads them at runtime; it must never embed their values in source.
Vault fieldEphemeral browser memoryBehavior
Usernamecredentials_usernameUsed for the portal identity field.
Passwordcredentials_passwordWrite-only secret resolved for the session.
TOTP seedcredentials_otp_codeOnly the current generated code enters memory; long sessions refresh it. The seed never does.
Static PINcredentials_pinAvailable only when the portal has a separate static factor.
Phone numbercredentials_phone_numberE.164 routing metadata for supported MFA activities; not an SMS provider.

MFA and human gates

Automate known factors, hand off consent and unknown challenges.

Some authentication can be deterministic; some must remain an explicit human action. Design both paths instead of treating every challenge as a selector problem.

Good automation candidates

  • Username and password form entry.
  • TOTP generated from the stored seed.
  • A known static PIN field.
  • Session restoration and deterministic post-login checks.

Good human gates

  • New-device consent and terms acceptance.
  • CAPTCHA or page-side verification.
  • Push approval or an OTP channel not integrated with XY.
  • Any step that requires an accountable person's judgment.

Rotate and revoke

Change the secret without changing the workflow.

The public credential ID is stable across rotation. Workflows do not need to be rebuilt just because the portal password changes.
Replace or revoke
curl --fail-with-body --request POST \
  --header "Authorization: Bearer ${XY_API_KEY}" \
  --header "Content-Type: application/json" \
  "${XY_API_BASE}/credentials/cred_REPLACE/rotations" \
  --data @replacement.json

# The public ID stays the same, so promoted workflows use the replacement next run.
curl --fail-with-body --request DELETE \
  --header "Authorization: Bearer ${XY_API_KEY}" \
  "${XY_API_BASE}/credentials/cred_REPLACE"