credential item, or a user can approve access to logins that stay in their 1Password account.
Choose a path
you or your agent must ask the end user whether they want to use 1Password for the website’s login. if they choose 1Password, link their 1Password account and request the login through 1Password brokered approval. if they don’t, or if that path doesn’t produce a usable login for any reason, your application should tell the user that 1Password did not work and fall back to KERNEL-hosted collection. see fall back to KERNEL-hosted collection for when to switch. keep in mind the limits of 1Password’s api: the login must be in a private vault that isn’t shared, and passkeys aren’t supported. if the user’s login is in a shared vault or the user signs in with a passkey, fall back to KERNEL-hosted collection.
neither path confirms that the website accepted the login. check the page after
filling.
KERNEL-hosted credential collection
KERNEL-hosted collection works for any user and is the fallback. create acredential item with provider: "kernel", present its collect action to the user, then invoke fill. see credential items for the full flow.
1Password brokered approval
brokered approval uses 1Password’s Agentic Autofill. the user reviews each access request in the 1Password app on their own device and chooses which logins to grant. the 1Password browser extension, which KERNEL takes care of loading into the vault-attached browser, then fills the granted login into the page. credential values are never returned by KERNEL’s api or passed through your application or model context. check 1Password’s supported accounts, vaults, and apps before you plan a rollout.How credentials are protected
- the user chooses the exact logins to grant in the 1Password app.
- KERNEL stores encrypted connection material and credential references in its items, not the login values.
- the 1Password extension fetches the credential and fills it into the page. KERNEL’s api returns a status, never the values.
- KERNEL checks that the page shares the origin of an approved login before it fills.
- KERNEL locks the browser while the values are in the page. see fill and submit.
- on
fillFailedorautosubmitFailed, the extension clears what it filled before it returns. - the destination website necessarily receives the credential, and its scripts can observe it.
- use a dedicated browser for each user, and don’t load extensions you don’t trust.
Choose an OAuth client
every 1Password connection belongs to an oauth client. 1Password shows the client’s name and icon on the consent screen and in the approval prompt, so the choice decides what your users see and how much of the account linking flow you need to build yourself. start with the KERNEL-managed oauth client: it’s the quickstart, and KERNEL runs account linking for you. your own oauth client is an advanced option for when your users must see your integration’s name and icon and you can run the oauth flow yourself.KERNEL-managed OAuth client (recommended)
tell your users that KERNEL is the browser provider that fills their logins through the 1Password extension, and that neither KERNEL nor your agent handles the login values. then:- create a
credential_accountitem to link the user’s 1Password account. see connect a 1Password account. - create a
credentialitem withaccountset to that item’s key to describe the login you need. see define a login request. - in a vault-attached browser, invoke
1pw_create_access_request, give the user the approval link, and poll1pw_access_request_status. see request access and hand off approval. - once the user approves, invoke
1pw_fillon that item in a browser session. see fill and submit.
Your own OAuth client (advanced)
you’re responsible for the full account linking flow. follow 1Password’s guides:- register an oauth client with an https redirect uri. see go to production.
- run the authorization code flow with pkce (
S256) and validatestate. see connect a user. - capture the integration key from your callback’s url fragment, exchange the code, and refresh the access token from your backend. see store keys and tokens.
- revoke the connection when the user disconnects. see disconnect a user.
- create a
credentialitem with the user’saccess_tokenandintegration_keyto describe the login you need. see use your own oauth client. - before each task, refresh the access token on your backend and send it with
1pw_update_access_token. see replace a stored access token. - in a vault-attached browser, invoke
1pw_create_access_request, give the user the approval link, and poll1pw_access_request_status. see request access and hand off approval. - once the user approves, invoke
1pw_fillon that item in a browser session. see fill and submit.
Connect a 1Password account
create acredential_account item in the user’s vault. it returns
state.status: "pending_authorization" and an action named
1password_oauth. present action.url to the signed-in user in your
application, outside the agent-controlled browser. the user signs in to
1Password and approves the connection. this path uses KERNEL’s oauth client;
credential_account items don’t accept a custom one. to use your own client,
skip the account and supply your own tokens.
the authorization url expires after a short time. repeating the same upsert
returns the current url while it’s valid and issues a new one after it
expires. a
wait read keeps holding while the status is
reconnect_required, so check the status instead of waiting for it to change.
Recover a failed account link
if linking the account fails in a way KERNEL can recover from, thecredential_account advertises 1pw_recover and state.status_reason
describes the failure. invoke it to get a new 1password_oauth action, and
present its url to the user as you did when connecting. after recovery
completes, start a new authorization on the same item by repeating the account
upsert. don’t delete the account to recover, and don’t retry recovery
automatically.
Define a login request
create acredential item with provider: "1password" and account set to
the key of a connected credential_account in the same vault. the item stores
the account’s key, not its id, and returns it in spec.account. requests
uses 1Password’s version 2 credential request format with one to five login
entries, each with an https website. the item stores no values or selectors.
goal accepts up to 140 characters, each entry’s reason up to 100, and an
entry can include one to five keywords of up to 50 characters each. the new
item starts in pending_authorization and advertises
1pw_create_access_request. the source, account, and requests are immutable;
repeating the same upsert returns the current item, and a different spec at
the same key returns 409. use a new item key for different logins. the
deprecated website shorthand is still accepted for account-backed items, but
supply requests for new items.
Use your own OAuth client
instead ofaccount, supply the user’s access_token and the matching
integration_key that your oauth client received from 1Password. KERNEL checks
that they belong together, stores both encrypted on this item, and never
returns either. set access_token_expires_at from the token response’s
expires_in so KERNEL knows when the token stops working; it must be in the
future, and the item returns it in spec.access_token_expires_at. these items
require requests.
account or both secrets, never both; a mismatched or incomplete pair
returns 400. repeating the create with identical values returns the current
item. a create at the same key with a different token, key, expiry, or
requests returns 409, so don’t use the upsert to rotate the token. after
access_token_expires_at passes, the item stops advertising
1pw_create_access_request, 1pw_access_request_status, and 1pw_fill, and
1pw_fill returns 409 until you replace the token. the token response and
integration key in these samples stand for values your backend already holds;
don’t pass them through a model.
Replace a stored access token
1Password access tokens are short-lived, so refresh the token on your backend as 1Password describes and invoke1pw_update_access_token with the new access_token before you
request access, poll, or fill. the new token must match the stored integration
key. the operation replaces only the token:
the integration key, requests, pending access request, approved references,
and state.status stay as they were. set access_token_expires_at to record
the new expiry, or omit it to clear the old one.
1pw_update_access_token whenever no other
1Password operation is in progress; during one, it returns 409. updating the
token doesn’t contact 1Password and doesn’t retry a pending or uncertain
operation.
Request several logins
arequests object can hold up to five login entries, so one approval can
cover several logins. the user can approve some entries and not others. when
approved entries share an origin, pass entry_id to 1pw_fill to choose one.
reason and keywords overrides at request time work only when the item has a
single entry.
Request access and hand off approval
create a browser with the vault attached, then invoke1pw_create_access_request with its browser_id. you don’t install anything:
KERNEL loads the 1Password extension into that browser on demand the first time
an operation needs it, then creates the access request through the extension.
goal, reason, and keywords in the operation override the item’s values
for this request.
action named 1password_access_approval. its url
is a native onepassword://grant-brokered-access link and instructions
describes the handoff. present the link to the end user who owns the 1Password
account. they open it on the device where they use the 1Password app, choose
the logins, and approve or deny there. the link grants nothing until they
approve. 1Password closes the unlock and approval prompts after 2 minutes; if
the user doesn’t finish, create a new credential item to send a new request. an item
accepts only one open access request.
the approval link carries your goal, reasons, and websites. don’t log it, don’t
pass it through a model, and deliver it to the user’s device over an
authenticated channel. see 1Password’s
approval guide.
state.access_request reports non-secret request state, such as its id,
state, entries, granted_count, and whether a fillable reference exists
(has_autofill_token). other fields are echoed from 1Password’s response when
it supplies them.
don’t automatically retry a failed request. if the call fails before KERNEL
dispatches the request to 1Password, the item still advertises
1pw_create_access_request. if it fails after dispatch, the outcome is
uncertain: a request might exist in 1Password. the item stays blocked in
pending_authorization with no approval action and no available operations,
and KERNEL doesn’t offer a way to retry or reset it. ask the account owner to
check the 1Password app for a pending request instead of sending another.
Poll for the decision
after you present the approval link, invoke1pw_access_request_status with a
vault-attached browser_id until the status leaves pending_authorization.
timeout_seconds accepts 0–120 and defaults to 10. KERNEL records the decision
only when you poll; a wait read of the item doesn’t observe approval.
declined and failed are final for the item; use a new key to request
again. an item with several entries also moves to failed if 1Password
doesn’t report which approved login belongs to which website;
state.status_reason then recommends separate credential items. if
1Password resolves a single-entry request without exactly one matching login,
the item returns to pending_authorization, state.status_reason explains why,
and you can invoke 1pw_create_access_request on the same item again.
approved references stay encrypted and are only usable by 1pw_fill. ready
means an approval was recorded, not that 1Password will honor it
indefinitely.
How long a grant lasts
the user approves once per login, not once per fill. while the grant lasts,1pw_fill can fill that login as often as the task needs without prompting the
user again.
- at launch, 1Password keeps a grant valid for 30 days. configurable lifetimes are planned.
- a grant isn’t tied to a session or task. if you promise your users approval per session, create a new
credentialitem and access request for each session. - a grant ends sooner if the connection is revoked or expires. a connection lasts about 90 days at most, and less if its tokens stop being refreshed.
- KERNEL doesn’t track the grant’s lifetime, so the item stays
readyafter the grant ends and fills fail. to ask again, create a newcredentialitem; areadyitem doesn’t accept another access request.
Fill and submit
navigate the attached browser to the page with the username and password form, not a page that asks the user to choose a sign-in method. then invoke1pw_fill with
the browser’s session id and the exact current top-level page_url. the url
must match exactly one open page and share the origin of an approved entry.
when more than one approved entry has that origin, pass its entry_id from
state.access_request.entries. the extension selects the fields, fills them,
and submits the form; you can’t supply selectors or values.
fill_submitted means the extension reported that it submitted the form. if the extension fills
the form but can’t submit it, it clears what it filled and KERNEL returns
fill_failed. a submitted form doesn’t mean the login succeeded.
for a sign-in that spans several pages, such as a username page, a password
page, and a one-time password page, invoke 1pw_fill again on each page. each
page must share the origin of the approved entry, and every fill is a new
request to 1Password, so an ended grant fails at the next fill.
exclusive browser control during autofill: while
1pw_fill runs, KERNEL
gives the autofill operation exclusive control of the browser. new CDP,
WebDriver, and browser api requests are rejected with 423 Locked, and
existing control connections are interrupted, not paused. reconnect after the
call returns. only KERNEL’s autofill connection can control the browser until
1pw_fill returns.this prevents concurrent automation from reading the page while credential
values are present. it does not isolate credentials from the destination
page, its scripts, or other extensions in the browser. live view isn’t part of
the lock: anyone with the browser’s live view can watch and send input during
the fill, so don’t share it with anyone who shouldn’t see the login.entry_id. timeout_ms accepts 1–30,000 and
defaults to 30,000.
Fall back to KERNEL-hosted collection
when the 1Password path can’t give you a usable login, create a separatecredential item with provider: "kernel" and
collect the login from the user
instead. switch when:
- the user doesn’t want to use 1Password, the login is in a shared vault or is a passkey, or their account isn’t in 1Password’s supported list.
- account linking doesn’t reach
connected, for example because the user declined consent. - the access request ends
declinedorfailed, or the user doesn’t approve it before the prompt closes. 1pw_fillkeeps returningfill_failedon the website’s login form.- a stored access token can’t be refreshed or the grant has ended, and the user doesn’t want to connect or approve again.
fill_unknown, check the page before you fall back; the extension might
already have submitted the form. tell the user why you’re asking for the login
again.
Delete items
delete a 1Passwordcredential item to discard its approval references and,
for a stored-token item, its encrypted token and key. delete every
credential item that references an account before deleting the
credential_account; otherwise the api returns 409. deleting the account
removes KERNEL’s stored connection. deleting either item doesn’t remove the
connection or revoke the token in the user’s 1Password account. if you use your
own oauth client, revoke the connection from your backend when the user
disconnects; see 1Password’s
disconnect guide.
Limitations
- not secret isolation: for each access request, status check, and fill, KERNEL gives the extension inside the attached browser access to the connected account or supplied token, and it doesn’t remove the extension afterward. use a dedicated browser for 1Password operations, don’t give untrusted automation access to it, and don’t load extensions you don’t trust alongside it. the filled values are in the page between fill and submit.
- private vaults only, no passkeys: 1Password’s api can grant only logins stored in the user’s private, non-shared vault, and it doesn’t support passkeys. see 1Password’s supported list.
- grants expire: 1Password grants last 30 days at launch and end sooner if the connection ends.
readydoesn’t expire with them; see how long a grant lasts. - up to five logins per item: each
credentialitem carries one to five https login entries. - you manage your own oauth client’s tokens: KERNEL doesn’t refresh or revoke a supplied access token. refresh it on your backend and replace it with
1pw_update_access_tokenbefore each task. - submission isn’t authentication:
fill_submittedmeans the form was submitted, not that the login succeeded. confirm the result on the page. - no automatic retries: access requests, recovery, and inconclusive fills can have effects in 1Password or on the website. an access request with an uncertain outcome stays blocked; don’t send another automatically.
Related
- vaults overview: resource model, scope, and browser attachment.
- credential items: KERNEL-hosted collection.
- fill browser fields: selector-based fill for KERNEL credentials.
- 1Password for managed auth: a separate integration that reads 1Password items with a service account during managed auth logins.