Skip to content

Commit 89f3f1b

Browse files
committed
Merge remote-tracking branch 'origin/main' into hypeship/1pw-fill-unknown-wording
2 parents 3c7e8e4 + 147226a commit 89f3f1b

1 file changed

Lines changed: 34 additions & 31 deletions

File tree

‎vaults/1password.mdx‎

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ KERNEL-hosted collection works for any user and is the fallback. create a `crede
4646
brokered approval uses 1Password's
4747
[Agentic Autofill](https://www.1password.dev/agentic-autofill/partners). the user
4848
reviews each access request in the 1Password app on their own device and chooses
49-
which logins to grant. the 1Password browser extension, which KERNEL takes care of loading into
50-
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
49+
which logins to grant. KERNEL creates the access request and reads its status from
50+
1Password directly, so no browser is involved until you fill. the 1Password browser
51+
extension, which KERNEL takes care of loading into the vault-attached browser, then fills
52+
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
5153
[supported accounts, vaults, and apps](https://www.1password.dev/agentic-autofill/partners#supported-today)
5254
before you plan a rollout.
5355

@@ -89,8 +91,8 @@ the login values. then:
8991

9092
1. create a `credential_account` item to link the user's 1Password account. see [connect a 1Password account](#connect-a-1password-account).
9193
2. create a `credential` item with `account` set to that item's key to describe the login you need. see [define a login request](#define-a-login-request).
92-
3. in a vault-attached browser, invoke `1pw_create_access_request`, give the user the approval link, and poll `1pw_access_request_status`. see [request access and hand off approval](#request-access-and-hand-off-approval).
93-
4. once the user approves, invoke `1pw_fill` on that item in a browser session. see [fill and submit](#fill-and-submit).
94+
3. invoke `1pw_create_access_request`, give the user the approval link, and poll `1pw_access_request_status`. neither needs a browser. see [request access and hand off approval](#request-access-and-hand-off-approval).
95+
4. once the user approves, create a vault-attached browser and invoke `1pw_fill` on that item. see [fill and submit](#fill-and-submit).
9496

9597
#### Your own OAuth client (advanced)
9698

@@ -105,8 +107,8 @@ then:
105107

106108
1. create a `credential` item with the user's `access_token` and `integration_key` to describe the login you need. see [use your own oauth client](#use-your-own-oauth-client).
107109
2. before each task, refresh the access token on your backend and send it with `1pw_update_access_token`. see [replace a stored access token](#replace-a-stored-access-token).
108-
3. in a vault-attached browser, invoke `1pw_create_access_request`, give the user the approval link, and poll `1pw_access_request_status`. see [request access and hand off approval](#request-access-and-hand-off-approval).
109-
4. once the user approves, invoke `1pw_fill` on that item in a browser session. see [fill and submit](#fill-and-submit).
110+
3. invoke `1pw_create_access_request`, give the user the approval link, and poll `1pw_access_request_status`. neither needs a browser. see [request access and hand off approval](#request-access-and-hand-off-approval).
111+
4. once the user approves, create a vault-attached browser and invoke `1pw_fill` on that item. see [fill and submit](#fill-and-submit).
110112

111113
on either path, if a step doesn't produce a usable login,
112114
[fall back to KERNEL-hosted collection](#fall-back-to-kernel-hosted-collection).
@@ -136,15 +138,16 @@ sequenceDiagram
136138
App->>OP: exchange code for tokens
137139
App->>K: upsert credential (access_token, integration_key)
138140
end
139-
App->>K: 1pw_create_access_request (browser_id)
140-
K->>B: load extension on demand, create request
141+
App->>K: 1pw_create_access_request
142+
K->>OP: create access request
141143
K-->>App: 1password_access_approval action
142144
App->>U: present approval link
143145
U->>OP: approve in the 1Password app
144-
App->>K: 1pw_access_request_status (browser_id)
146+
App->>K: 1pw_access_request_status
147+
K->>OP: read request status
145148
K-->>App: state ready
146149
App->>K: 1pw_fill (browser_id, page_url, entry_id)
147-
K->>B: extension fills and submits
150+
K->>B: load extension on demand, then fill and submit
148151
K-->>App: fill_submitted, fill_failed, or fill_unknown
149152
```
150153

@@ -471,22 +474,17 @@ kernel.vaults.items.upsert(
471474

472475
### Request access and hand off approval
473476

474-
create a browser with the vault attached, then invoke
475-
`1pw_create_access_request` with its `browser_id`. you don't install anything:
476-
KERNEL loads the 1Password extension into that browser on demand the first time
477-
an operation needs it, then creates the access request through the extension.
478-
`goal`, `reason`, and `keywords` in the operation override the item's values
479-
for this request.
477+
invoke `1pw_create_access_request` on the item. KERNEL creates the access
478+
request with 1Password directly, so you don't need a browser yet; you create
479+
one when you're ready to [fill](#fill-and-submit). `goal`, `reason`, and
480+
`keywords` in the operation override the item's values for this request.
480481

481482
<CodeGroup>
482483

483484
```typescript TypeScript
484-
const browser = await kernel.browsers.create({ vaults: [{ id: vault.id }] });
485-
486485
const requested = await kernel.vaults.items.performOperation("github-login", {
487486
id_or_name: vault.id,
488487
type: "1pw_create_access_request",
489-
browser_id: browser.session_id,
490488
});
491489
if (requested.type !== "credential" || requested.action?.name !== "1password_access_approval") {
492490
throw new Error("1Password didn't return an approval link");
@@ -495,13 +493,10 @@ if (requested.type !== "credential" || requested.action?.name !== "1password_acc
495493
```
496494

497495
```python Python
498-
browser = kernel.browsers.create(vaults=[{"id": vault.id}])
499-
500496
requested = kernel.vaults.items.perform_operation(
501497
"github-login",
502498
id_or_name=vault.id,
503499
type="1pw_create_access_request",
504-
browser_id=browser.session_id,
505500
)
506501
if (requested.type != "credential" or requested.action is None or
507502
requested.action.name != "1password_access_approval"):
@@ -531,17 +526,19 @@ authenticated channel. see 1Password's
531526
it supplies them.
532527

533528
don't automatically retry a failed request. if the call fails before KERNEL
534-
dispatches the request to 1Password, the item still advertises
535-
`1pw_create_access_request`. if it fails after dispatch, the outcome is
536-
uncertain: a request might exist in 1Password. the item stays blocked in
529+
dispatches the request to 1Password, or 1Password rejects it (`provider_rejected`
530+
with a `4xx` status), nothing was created and the item still advertises
531+
`1pw_create_access_request`; fix the cause, such as an expired token or a
532+
disconnected account, before you try again. if it fails after dispatch with a
533+
`5xx` or a network error, the outcome is uncertain: a request might exist in 1Password. the item stays blocked in
537534
`pending_authorization` with no approval action and no available operations,
538535
and KERNEL doesn't offer a way to retry or reset it. ask the account owner to
539536
check the 1Password app for a pending request instead of sending another.
540537

541538
### Poll for the decision
542539

543-
after you present the approval link, invoke `1pw_access_request_status` with a
544-
vault-attached `browser_id` until the status leaves `pending_authorization`.
540+
after you present the approval link, invoke `1pw_access_request_status` until
541+
the status leaves `pending_authorization`. it doesn't need a browser.
545542
`timeout_seconds` accepts 0–120 and defaults to 10. KERNEL records the decision
546543
only when you poll; a `wait` read of the item doesn't observe approval.
547544

@@ -553,7 +550,6 @@ while (item.type === "credential" && item.state.status === "pending_authorizatio
553550
item = await kernel.vaults.items.performOperation("github-login", {
554551
id_or_name: vault.id,
555552
type: "1pw_access_request_status",
556-
browser_id: browser.session_id,
557553
timeout_seconds: 60,
558554
});
559555
}
@@ -569,7 +565,6 @@ while item.type == "credential" and item.state.status == "pending_authorization"
569565
"github-login",
570566
id_or_name=vault.id,
571567
type="1pw_access_request_status",
572-
browser_id=browser.session_id,
573568
timeout_seconds=60,
574569
)
575570
if item.type != "credential" or item.state.status != "ready":
@@ -612,7 +607,9 @@ see 1Password's [how long a grant lasts](https://www.1password.dev/agentic-autof
612607

613608
### Fill and submit
614609

615-
navigate the attached browser to the page with the username and password form,
610+
create a browser with the vault attached; you don't install anything, because
611+
KERNEL loads the 1Password extension into it on demand the first time you fill.
612+
navigate it to the page with the username and password form,
616613
not a page that asks the user to choose a sign-in method. then invoke `1pw_fill` with
617614
the browser's session id and the exact current top-level `page_url`. the url
618615
must match exactly one open page and share the origin of an approved entry.
@@ -647,6 +644,9 @@ request to 1Password, so an ended grant fails at the next fill.
647644
<CodeGroup>
648645

649646
```typescript TypeScript
647+
const browser = await kernel.browsers.create({ vaults: [{ id: vault.id }] });
648+
// Navigate the browser to https://portal.example.com/login before filling.
649+
650650
const approved = await kernel.vaults.items.retrieve("example-portal-logins", {
651651
id_or_name: vault.id,
652652
});
@@ -672,6 +672,9 @@ if (result.status === "fill_failed") {
672672
```
673673

674674
```python Python
675+
browser = kernel.browsers.create(vaults=[{"id": vault.id}])
676+
# Navigate the browser to https://portal.example.com/login before filling.
677+
675678
approved = kernel.vaults.items.retrieve("example-portal-logins", id_or_name=vault.id)
676679
if approved.type != "credential" or approved.state.provider != "1password":
677680
raise RuntimeError("unexpected item")
@@ -744,7 +747,7 @@ disconnects; see 1Password's
744747

745748
## Limitations
746749

747-
- **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.
750+
- **not secret isolation:** for each 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. access requests and status checks don't involve the browser. 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.
748751
- **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](https://www.1password.dev/agentic-autofill/partners#supported-today).
749752
- **grants expire:** 1Password grants last 30 days at launch and end sooner if the connection ends. `ready` doesn't expire with them; see [how long a grant lasts](#how-long-a-grant-lasts).
750753
- **up to five logins per item:** each `credential` item carries one to five https login entries.

0 commit comments

Comments
 (0)