← Public packages
@kentcdodds/onepassword
Resolve 1Password Connect item fields for secret-aware fetch with website host allowlisting.
connect/deployment-guide.ts
115 lines · 5.4 KB · TypeScript/**
* Return markdown deployment instructions for 1Password Connect on Fly.io.
*
* Use this deployment guide when a Kody workflow needs Connect-on-Fly setup steps,
* required Kody secret names, and bind checklist without secret values.
*/
export default async function deploymentGuide() {
return [
'# 1Password Connect on Fly — deployment guide',
'',
'## Overview',
'',
'Deploy official images `1password/connect-api:latest` and',
'`1password/connect-sync:latest` as a **multi-container Fly Machine**.',
'Fly HTTPS terminates at the proxy and forwards to connect-api `:8080`.',
'',
'Default app name: `kody-onepassword-connect`',
'Default URL: `https://kody-onepassword-connect.fly.dev`',
'',
'## 1. Create Connect server credentials (1Password Developer)',
'',
'1. In 1Password → Developer → Connect servers, create a server.',
'2. Download `1password-credentials.json`.',
'3. Create a Connect access token with read access to the vaults you need.',
'4. Base64-encode the credentials file locally (Machines `config.files.raw_value` expects Base64; container `OP_SESSION` is the file path,',
' not raw JSON). Example: `base64 -w0 1password-credentials.json` (Linux) or',
' `base64 < 1password-credentials.json | tr -d \'\\n\'` (macOS).',
'',
'## 2. Save Kody secrets (never paste values into chat)',
'',
'### OP_SESSION (required for deploy-fly)',
'',
'[Save ONEPASSWORD_CONNECT_OP_SESSION](https://kody.codes/account/secrets/new?name=ONEPASSWORD_CONNECT_OP_SESSION&description=Base64%20encoding%20of%201password-credentials.json%20(not%20raw%20JSON).%20Fly%20Connect%20reads%20this%20as%20OP_SESSION%20via%20connect%2Fdeploy-fly%20setSecrets.&allowedHosts=api.machines.dev%2Capi.fly.io&scope=user)',
'',
'Store **Base64(credentials.json)** — not the raw JSON file contents.',
'`./connect/deploy-fly` mounts Base64 via `config.files` and cannot Base64 inside package code without reading the',
'secret, so the value must already be Base64 when saved.',
'',
'Approve hosts **`api.machines.dev`** and **`api.fly.io`** on this secret',
'(placeholders expand only inside secret-aware `fetch` to those Fly APIs).',
'Package grant for `@kentcdodds/onepassword` should already be set; if deploy',
'complains about grants, add the package on the secret.',
'',
'### Legacy name (do not use raw JSON as OP_SESSION)',
'',
'If you previously saved raw JSON as `ONEPASSWORD_CONNECT_CREDENTIALS_JSON`,',
'do **not** point deploy at it. Re-save Base64 under',
'`ONEPASSWORD_CONNECT_OP_SESSION` instead. Deploy-fly will fail closed rather',
'than silently send raw JSON as Fly `OP_SESSION`.',
'',
'### Connect token (door key + smoke)',
'',
'[Save / update ONEPASSWORD_CONNECT_TOKEN](https://kody.codes/account/secrets/new?name=ONEPASSWORD_CONNECT_TOKEN&description=1Password%20Connect%20Server%20token%20(Authorization%3A%20Bearer)%20used%20as%20the%20door%20key%20for%20the%201password%20secret%20provider%20and%20API%20smoke%20tests&allowedHosts=kody-onepassword-connect.fly.dev&scope=user)',
'',
'If the secret already exists, edit it and set `allowedHosts` to include',
'`kody-onepassword-connect.fly.dev` (and any other Connect hosts you call).',
'',
'### flyApiToken',
'',
'`flyApiToken` should already exist for `@kentcdodds/fly` / Discord Fly deploys.',
'It must allow hosts **`api.machines.dev`** and **`api.fly.io`**:',
'',
'[Update flyApiToken hosts](https://kody.codes/account/secrets/new?name=flyApiToken&description=Fly.io%20API%20token%20for%20Machines%20API%20and%20GraphQL%20(api.machines.dev%20%2B%20api.fly.io)&allowedHosts=api.machines.dev%2Capi.fly.io%2Cdocs.machines.dev%2Cfly.io&scope=user)',
'',
'## 3. Deploy',
'',
'```js',
"import deploy from 'kody:@kentcdodds/onepassword/connect/deploy-fly'",
'const result = await deploy()',
'// => { ok: true, appName, url, region, ... } (no secret values)',
'```',
'',
'Secret placeholders appear only inside outbound Fly `fetch` calls',
'(`Authorization: Bearer {{secret:flyApiToken}}` and JSON body',
'`files.raw_value: {{secret:ONEPASSWORD_CONNECT_OP_SESSION}}`), matching the',
'Discord `./proxy/deploy-fly` pattern. Module-level transforms of secret',
'strings are not expanded.',
'',
'Or retrieve files only:',
'',
'```js',
"import source from 'kody:@kentcdodds/onepassword/connect/source'",
'const bundle = await source()',
'```',
'',
'## 4. Smoke',
'',
'- `GET https://kody-onepassword-connect.fly.dev/heartbeat` (unauthenticated)',
'- `GET https://kody-onepassword-connect.fly.dev/v1/vaults` with',
' `Authorization: Bearer {{secret:ONEPASSWORD_CONNECT_TOKEN}}`',
'',
'## 5. Bind sealed provider',
'',
'```js',
"import { kody } from 'kody:runtime'",
'',
'export default async function main() {',
' return await kody.secretProviderBind({',
" provider: '1password',",
" package_id: '7603a38f-6d3f-44e4-beca-b10196b38008',",
" door_secret_name: 'ONEPASSWORD_CONNECT_TOKEN',",
" config: { connectHost: 'https://kody-onepassword-connect.fly.dev' },",
' })',
'}',
'```',
'',
'## Shape details',
'',
'- Shared volume mount: `/home/opuser/.op/data` (Machine `temp_dir` named `opdata`)',
'- Credentials via Fly secret `OP_SESSION` = value of `ONEPASSWORD_CONNECT_OP_SESSION` (Base64)',
'- Manual bus (no NET_BROADCAST): API `11223` ↔ sync `11224` on `localhost`',
'- Sync uses `OP_HTTP_PORT=8081` so it does not collide with API `8080`',
'',
].join('\n')
}