Search Composal documentation

Search public documentation, commands, and release notes.

Managed credentials

Manage test-account passwords, authenticator codes, email inboxes, browser sessions, and passkeys. Add, refresh, or disable credentials for Verify runs.

Contents

Add a credential

Composal encrypts and stores managed credentials for runs to use when signing in. Use them with any app. For a Better Auth app, Better Auth sign-in avoids storing anything for your app.

When available in onboarding, you can choose Use the Composal managed Google account instead. Give agent@agents.composal.ai the test access it needs in your app and choose the managed account on Test account. Composal manages a Google passkey for sign-in; its private key is not added to your project's secrets. A run can use the passkey once; if Google requires another sign-in challenge, use your own test account. The identity is shared across customers and can access every app and workspace that has invited it, including another customer's; grant it only test access. Runs can follow redirects and open other HTTP or HTTPS origins, including separate authentication domains and third-party resources. The managed password can only be entered on Google's sign-in origin. Live images and recordings are temporarily unavailable while Google sign-in may display the managed credentials, so the live view may appear frozen until sign-in finishes. Use your own test account when your app requires API setup and cleanup actions. This option does not read invitation email for you, and shared-account runs may wait while another run uses the account. Deep Scan can use the managed account. Its browser workers use the shared account one at a time, and API scripting is unavailable.

  1. Open your project's Credentials and choose Add Credential.
  2. Choose how agents sign in: Sign in with a browser, Password, Email link / OTP or Session cookies. Google, GitHub, Passkey and Custom are also visible under More sign-in methods.
  3. Give the credential a Name that says who it is, such as Staging admin, and fill in the method's fields below. Google needs an authenticator setup key; see Google test accounts for how to prepare the account.
  4. Optional: open the instructions section to add When to Use, such as Use for admin and billing journeys, and Login Instructions, such as Choose the Acme workspace. Login is complete when the dashboard is visible. Verify uses the first to choose between credentials and gives the second to the agent.
  5. Choose Save test account.

Password and authenticator

Choose Password for an email or username and password form. Enter the Login page, the Email / Username and the Password.

For authenticator-app 2FA, open Instructions and two-factor authentication and enter the Authenticator Secret: the Base32 setup key or otpauth:// URI your app shows when you enroll an authenticator, not a one-time code. Agents generate a fresh code each time they sign in. Runs that share an authenticator sign in one at a time, so a code is never reused.

Find an authenticator setup key

  1. Sign in to your app as the test account and open its two-factor or security settings.
  2. Choose to set up an authenticator app. The app shows a QR code.
  3. Choose the option to show the key instead, often labelled Can't scan it? or Enter a setup key, and copy it.
  4. Paste the key into Authenticator Secret in Composal.
  5. Finish setup in your app with a code from any authenticator app that has the same key.

If the test account already has an authenticator and you no longer have its key, remove that authenticator in your app and set it up again to get a new key.

The first run to sign in shares its signed-in app session. Later scenarios can reuse that copy in their own browsers, while keeping the password and authenticator available if they need to sign in again. Runs on that account still wait for its sign-in turn, so they cannot use its authenticator concurrently. Unrelated accounts can run in parallel.

If the copy is signed out, for example after a scenario logs out, it is discarded. A run with the account's password and authenticator can sign in again. A copy lasts up to two hours and is deleted when the account is edited or disabled.

The run page shows whether the first run shared its session and, when it could not, why; the account's other scenarios show that they are waiting for its sign-in turn.

If your app emails a verification link or a two-factor code after the password, turn on Use a Composal Email Address. Saving creates a Composal address in place of the username and shows it with an Inbox button. Sign up on your app with that address, open the verification email in the credential's Inbox, then edit the credential and save the password you chose. The credential shows Needs Password until then. During a run, the agent signs in with the address and password, then reads the emailed code or link from that inbox, with the same limits as an email-link credential.

Push approvals, SMS codes and other provider challenges need a person. Use a saved browser session for those apps.

Choose Email link / OTP for apps that sign in with magic links or emailed codes. Saving creates a dedicated Composal email address and shows it on the credential. Agents can register that address themselves when the app offers signup. If the app requires email and password, they use a private password saved with the credential and reuse it on later runs. For invite-only apps, invite the address before running. A rejected password on an existing account remains an authentication blocker; agents do not reset it automatically.

During a run, the agent requests a sign-in email and then reads that inbox to open the link or enter the code. It can read only messages that arrive after its run started, and only for the credential selected for that run. Scenarios that test signup need their own fresh inbox: assign one email-link credential to the signup persona for each signup you test. Once a scenario starts with that credential, Verify refuses another signup with it, including a run approved earlier. Create and assign a fresh inbox before preparing another signup; Verify does not create a new inbox automatically for each run.

Connected Scenarios can also use an emailed code after sign-in, for example when a borrower accepts terms issued by a loan officer. Assign the receiving Persona a credential with a Composal inbox and include requesting and entering the code in its steps. The runner reads that Persona's own inbox after the request, without asking the Persona to enter its email again. Codes stay private to the browser. State any resend limit in the Scenario; wait for delivery before requesting another code.

For a multi-persona journey whose sign-in email opens a separate authentication host, an administrator can configure email_link_auth_origins through the project credential API. Keep login_url pointing to the app's public sign-in or signup page. List the additional exact origins, such as https://auth.example.com, without paths, query strings, fragments or wildcards; an email-link credential accepts up to 20. The default is an empty list.

Save a request file containing the non-secret origin configuration, then update the credential:

JSON
{
  "email_link_auth_origins": ["https://auth.example.com"]
}
Bash
com api request verify project-credentials update --org your-org --project your-project \
  --id vaccount_example --body-file auth-origins.json --json

Prepare a new run after changing this setting. Verify captures the permitted login-mail origins for that actor; changing the origin policy during execution stops private-mail access. Invitation links keep their existing origin rules. This flow requires matching Rails, Roder and browser support; an older browser image refuses the additional grant before sign-in.

Google, GitHub and custom login

Google and GitHub describe your app's "Continue with Google" or "Continue with GitHub" button. They do not create a Composal OAuth integration. Enter a dedicated provider test account's email and password. GitHub needs its authenticator setup key if the account uses 2FA. Google always needs one: see Google test accounts. Google may refuse sign-in from an automated browser. If it does, sign in yourself and save the app session instead; saved storage stays scoped to the origin you capture.

Custom is a password login with extra steps. Its Login Instructions are required; describe each step and how to recognize that sign-in succeeded.

Saved browser sessions

A saved session lets runs start already signed in, after you complete sign-in yourself, including SSO, CAPTCHAs or push approvals. Composal saves only the app's cookies, local storage and IndexedDB for one origin. Sessions expire after 24 hours, or earlier if your app signs them out, so refresh them before you run.

The login browser accepts HTTP and HTTPS URLs, including IP addresses, localhost, internal hostnames and Google domains. Redirects and linked apps can open across origins. The address must be reachable from the cloud browser; localhost refers to that browser sandbox.

To sign in from Composal:

  1. Choose Add Credential → Sign in with a browser. Enter the Account Name and the app's HTTP or HTTPS App Login URL, then choose Start Login Browser.
  2. Choose Open Login Browser and sign in, including any MFA. The private browser stays open for 15 minutes.
  3. Return to Composal, confirm I’m signed in to the correct test account, and choose Save Browser Session.

To paste cookies instead, choose Session cookies. Enter the App URL and paste one cookie per line as name=value or name:"value". A copied Cookie header also works. Choose Upload File Instead to upload a session file saved by the CLI.

To create your first credential from the CLI with a private cloud browser:

Bash
com verify browser-session --org your-org --project your-project \
  --url https://app.example.com/login --login --name "Test admin"

Complete sign-in in the viewer, then press Enter in the CLI to save. --name is optional; it defaults to the app hostname followed by “browser session”. Use --account vaccount_example instead to refresh an existing credential.

To capture a session from your own computer, use the CLI. It opens a fresh Chrome profile, waits for you to sign in, then uploads only that app's state:

Bash
com verify browser-session --org your-org --project your-project --account vaccount_example \
  --url https://app.example.com/login --local-login

Type save when the app shows the expected account. --chrome-profile Default imports from an existing Chrome profile instead, and --login opens a private cloud browser. Add --skip-indexed-db when your app's IndexedDB caches exceed the 1 MiB limit and authentication does not depend on them.

A session works only on the origin it was saved for. Runs against another origin, such as a pull request preview, fail preparation until you save a session for that origin.

Passkeys

Choose Passkey under More sign-in methods to upload an enrolled software passkey's private JSON file. Enroll the passkey yourself in your app's security settings: agents can sign in with it but cannot enroll new passkeys. The upload is valid for 30 days and works only on the origin it was enrolled for. A passkey signs in one run at a time. Some providers reject software authenticators, so test it with one run first.

Generate and save a dedicated passkey from an interactive terminal:

Bash
com verify accounts enroll-passkey \
  --project storefront \
  --url https://test-app.example/account/passkeys \
  --sign-in-url https://test-app.example/login

The command uses your installed Google Chrome. It does not need Node, a repository checkout, a browser extension or a browser download. Use --chrome /path/to/chrome if Chrome is installed somewhere else. Sign in to Composal first and choose a project with --project or com switch.

  1. Choose an existing project credential or enter a name and username for a new one. Composal checks your permission to manage credentials before opening Chrome. You can also pass --account "Test user", or --name "Test user" --username qa@example.test.
  2. In the private Chrome window, sign in to the intended test account and create a passkey in its security settings. This creates a new credential in a software authenticator; it does not export a passkey from your password manager.
  3. Once the provider confirms registration, type VERIFY in the terminal. A fresh private Chrome profile opens with only the new passkey installed. Sign in using that passkey.
  4. Complete any additional password or verification step the provider requests. Once it confirms you are signed in to the correct account, type SAVE. Composal uploads the private key directly to the project's encrypted credential vault. The CLI prints metadata, never the key.

A passkey assertion may be followed by a provider password or other challenge. If the provider still requires those credentials, attach the passkey to an existing Google/password credential with --account; the command preserves its sign-in method and saved password/authenticator. New credentials created by this command use the passkey sign-in method.

For Google Workspace test accounts, we recommend a dedicated passkey with passwordless sign-in when your security policy permits it. Start with the organizational unit for test accounts, or use an explicitly approved organization-wide policy. Keep password and passkey access when skipping passwords is unavailable. Verify both account settings and a complete fresh sign-in before relying on passwordless access.

For a private file instead of an upload, use --out /private/path/verify-passkey.json and omit the project and credential flags. This mode works without a Composal login and uploads nothing. Local files are supported on macOS and Linux, are created exclusively with owner-only permissions, and can be uploaded in the Passkey field later. Remove the file after import and keep it out of chat, source control and recordings.

The whole ceremony expires after 15 minutes. Type cancel, close the private browser, or press Ctrl-C to stop; the temporary Chrome profiles are removed. If the provider already registered the new key but verification or saving fails, remove that key in its security settings before starting again. The command requires owner interaction and refuses --agent, --json and --non-interactive.

If enrollment and sign-in use different origins, set both URLs explicitly and pass the provider's RP domain with --rp-id, for example google.com. The resulting passkey is bound to the sign-in origin. Google can reject a browser or software authenticator, and this command does not override that decision. A local owner enrollment does not establish passwordless or hosted-runner acceptance.

Use credentials in runs

When you prepare a run, Verify picks each scenario's credential from the project, as described in how runs use credentials. To pin a credential to a persona, choose it as that persona's Credential.

Scenario steps use references to credential fields. When you edit a credential, Agent credential references lists keys such as VERIFY_…_USERNAME and VERIFY_…_PASSWORD. Bind project Personas to their configured Credentials; reference required credential fields in authored Scenario instructions. Managed-environment blueprints must also declare the keys each persona may use. Only the keys a run requests reach it.

Rotate, disable and remove

Organization administrators can edit a credential's guidance, rotate its password, and replace or remove its authenticator or browser session. Secret fields are write-only: leave them blank to keep the saved values. The username and guidance are visible metadata.

Disable blocks every value on the credential for future runs. It does not sign out a browser that is already signed in. Reconfiguring a disabled password credential requires a new password, and a disabled session or passkey requires a fresh file.

Delete permanently removes the credential and its saved secrets. If it has a Composal email address, its inbox and messages are also deleted, freeing the inbox slot. Past run reports remain available. Stop any runs or owner browsers using the credential before deleting it. If inbox cleanup is unavailable, the credential remains so you can retry.

Credential names are local labels: names such as Brand admin (prod) work with a Composal email address.

API and CLI

A project's credentials are available at /api/v1/organizations/{organization_id}/verification/projects/{project_id}/credentials: GET lists them, POST creates one, PATCH /{id} edits or rotates it, POST /{id}/disable disables it, and DELETE /{id}?permanent=true permanently deletes it and any Composal inbox. For older clients, DELETE without permanent=true still disables the credential. Writes accept the same fields as the form, plus passkey, browser_session or cookies for browser artifacts. Responses return metadata and credential references, never secret values. From the CLI, com verify admin --help lists the project credential commands; pass request bodies through a private --body-file or --body-stdin, never as arguments.

Next, see Better Auth sign-in for apps that can trust Composal directly.