Signed-in sites
Test pages behind a login by storing the login in the vault and starting a session that fills it in. The agent never sees the password.
Most apps have pages you only reach after you sign in. To test them, save the test user's login once in the vault. Then start a session with credentials turned on. The browser fills the login form for you. You do not put a password in a prompt, a goal or a script.
Use a test account, not a real person's account. The agent clicks and types in a real app, so give it a user with test data only.
What you need
- An API key with the member role or higher. Members can manage logins.
- A deployment with the vault enabled. If the API answers
invalid_inputwith "credentials are unavailable", ask your admin. - The app on a URL the cloud browser can open. See Test a local app and Protected sites.
1. Save the login
In the dashboard open Vault, then New credential. Or call the API:
curl -s -X POST "$API_URL/v1/credentials" \
-H "Authorization: Bearer $WEBAGENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"origin": "https://staging.example.com",
"username": "[email protected]",
"password": "'"$QA_PASSWORD"'",
"label": "Staging QA user"
}'$API_URL is your API host, https://api.us.webagent.lookover.ai once your workspace is live there. If your team gave you another URL, use that.
| Field | Meaning |
|---|---|
origin | Scheme, host and port, no path. For example https://staging.example.com or http://10.0.0.5:8080. A trailing slash is removed. The login is only used on this exact origin. |
username, password | The login. The reply never contains them. |
totpSecret | Optional. The seed of an authenticator app. The vault turns it into a one-time code when the page asks for one. |
namespace | Optional group, for example one per environment. Default default. |
label | Optional name for the list. |
The reply is the saved credential with its id (cred_us_...), origin, namespace, label, username and hasTotp. It has no password.
You can have one login per origin, namespace and username. A second one with the same three values fails with conflict.
Passwords and TOTP seeds are encrypted at rest and never returned by the API. Lists show the origin, username and label.
If your team keeps logins in 1Password or Bitwarden, an admin connects the provider once, and you create the credential with a source (provider id and reference) instead of a password.
2. Start a session that fills it
Pass credentials when the session opens. Open the login page with startUrl. run_task does this for you (step 3). To open the session yourself, use create_session:
{
"startUrl": "https://staging.example.com/login",
"credentials": true
}trueuses thedefaultnamespace. The browser fills the form but does not submit it. The task presses Sign in.{ "autoSubmit": true }also presses Enter after filling, so the page is signed in when the task starts.{ "namespace": "staging", "autoSubmit": true }picks a namespace as well.
When a page of that exact origin loads and shows a login form, the browser types the username and password. If the page asks for a one-time code and the login has a TOTP seed, it types the code too. A page is filled once per load.
3. Run the task
run_task takes credentials itself, so one call is enough. It opens the session, fills the login and runs the goal:
{
"goal": "Check that the dashboard shows the text Welcome. Report pass or fail and the reason.",
"startUrl": "https://staging.example.com/login",
"credentials": { "autoSubmit": true }
}From Claude Code or Codex:
Call run_task with startUrl https://staging.example.com/login, credentials
{"autoSubmit": true} and this goal: "Check that the dashboard shows the text Welcome.
Report pass or fail and the reason."This was run against the Test Arena sign-in page with a credential saved for https://webagent-test-web.pages.dev. The task started signed in and the text of the answer was:
Task finished (done) in 1 steps, $0.0007, 5 s.
Answer: PASS: the page shows the heading "Welcome, qa", which contains the text Welcome.
Session sess_us_... was closed.
For a pass/fail report call get_report with tsk_us_...credentials only applies when run_task opens the session, so it is refused together with sessionId (invalid_input: "credentials apply only when run_task opens the session (leave sessionId out)"). There is no field for a plain password.
With autoSubmit the page is already signed in when the task starts. Without it, the form is filled and the task has to submit it. A task has no assertions, so ok means the agent says it is done: read the answer, or call get_report with the task id for the report.
If several checks must share one signed-in browser, create the session first with create_session and the same startUrl and credentials, then call run_task for each check with its sessionId. Call stop_session at the end.
How the secret stays out of the agent's reach
- The session create request carries only your choice (
credentials), not the secret. - The runner that hosts the browser holds no vault key. When a login form appears, it asks the API for the login of that one origin, using the token of that one session.
- The values are typed into the page as input and are not written to the session record. The timeline only says that saved credentials were used for an origin.
- The agent gets a note that credentials were filled for the origin. It does not get the password.
- Each time the vault releases a login to a session, the API writes an audit entry with ids and no values.
Two limits of that promise. First, the agent reads the page like any visitor. If your app shows the username after sign-in, the agent can read it. Second, never type a password into a goal, a prompt or a skill steps list. Those texts are stored or sent to the model.
What does not work yet
- Skill runs cannot sign in. A skill run with
credentialsorprofileIdin its session is refused withinvalid_inputand does not start. Sosmoke_test,smoke-uat,authenticated-scanand the other skills see the signed-out view of your app. For a signed-in check userun_taskwithcredentials. To keep a real assertion, put the sign-in in thestepsofsmoke_testwith a throwaway test account: the step text is stored with the run. - Exact origin only. A login saved for
https://staging.example.comis not used onhttps://www.example.comor on another port. - Forms the browser cannot detect. The fill looks for a password field or a one-time-code field on page load. A login that appears only after other clicks may need the agent to reach it first.
Troubleshooting
| What you see | Likely cause |
|---|---|
| The agent reports a login page, nothing filled | No credential for that exact origin and namespace, or credentials was not set on the session. Check the Vault page. |
A skill run or smoke_test fails with invalid_input: "Signed-in skill runs are not available yet: remove session.credentials" | Skill runs cannot sign in yet. Remove the field, or use run_task with credentials instead. |
invalid_input "apply only when run_task opens the session" | You sent credentials together with sessionId. Leave sessionId out, or put credentials on create_session. |
conflict on create | The origin, namespace and username already exist. Edit the existing one. |
| Fill happens but sign-in fails | Wrong password or the test user is locked. Update the credential in the Vault. |
Protected sites
Test a staging site that sits behind a WAF, Vercel deployment protection, Cloudflare Access or an ngrok warning page, by sending your own bypass header.
Smoke tests in CI
Run a webagent smoke test after every deploy from a CI job with curl or the SDK, and fail the job when the test does not pass.