sondahub

sondahub / 1Password Connect sandbox

A 1Password Connect server mock for the Connect SDKs

The API a 1Password Connect server answers, by sondahub: vaults, items of every category with fields, sections, URLs and tags, generated passwords with their entropy, one-time-password fields that give the current code, files and their content, JSON Patch, filters and the activity log. Point the SDK’s Connect host here; no server to run, no account to open.

An independent imitation for testing. Not affiliated with, or endorsed by, 1Password.

Connect

Instead of
http://<your-connect-server>:8080
Connect host
https://api.sondahub.com/sandbox/1password-connect
Token
any bearer token — sondahub-connect-token
OpenAPI 3
https://api.sondahub.com/sandbox/1password-connect/openapi.json

Python (onepasswordconnectsdk)

from onepasswordconnectsdk.client import new_client

client = new_client('https://api.sondahub.com/sandbox/1password-connect', 'sondahub-connect-token')   # any token works

# carry the sandbox session from each answer to the next request
def keep(response):
    token = response.headers.get('X-Sondahub-Session')
    if token:
        client.session.headers['X-Sondahub-Session'] = token
client.session.event_hooks['response'] = [keep]

item = client.get_item('Admin console', 'Production')
print([(f.label, f.totp or f.value) for f in item.fields])

op CLI, through Connect

export OP_CONNECT_HOST=https://api.sondahub.com/sandbox/1password-connect
export OP_CONNECT_TOKEN=sondahub-connect-token
op item get Stripe --vault Production --fields credential

Import it. In Sonda: Import → From a URL, paste the OpenAPI address. You get a folder per resource and a request per operation, with example bodies and names from the seed, so most requests work as they are. Then set the auth: Bearer token sondahub-connect-token. Any client that imports OpenAPI 3 takes the same address.

Try it here

These examples share one session: run them in order and each sees what the one before it did.
The vaults
curl "https://api.sondahub.com/sandbox/1password-connect/v1/vaults" \
  -H "Authorization: Bearer sondahub-connect-token"
Items in Production
curl "https://api.sondahub.com/sandbox/1password-connect/v1/vaults/i7gwu4baaugmv7aapnir3saard/items" \
  -H "Authorization: Bearer sondahub-connect-token"
A login with a one-time password (see totp)
curl "https://api.sondahub.com/sandbox/1password-connect/v1/vaults/i7gwu4baaugmv7aapnir3saard/items/p7dw1zbar0s1wdaay8xkz7aaei" \
  -H "Authorization: Bearer sondahub-connect-token"
Find an item by title
curl "https://api.sondahub.com/sandbox/1password-connect/v1/vaults/i7gwu4baaugmv7aapnir3saard/items?filter=title%20eq%20%22Orders%20database%22" \
  -H "Authorization: Bearer sondahub-connect-token"
Create a login with a generated password
curl -X POST "https://api.sondahub.com/sandbox/1password-connect/v1/vaults/i7gwu4baaugmv7aapnir3saard/items" \
  -H "Authorization: Bearer sondahub-connect-token" \
  -H "Content-Type: application/json" \
  -d '{"vault":{"id":"i7gwu4baaugmv7aapnir3saard"},"title":"Grafana","category":"LOGIN","tags":["prod"],"urls":[{"href":"https://grafana.example.com","primary":true}],"fields":[{"id":"username","label":"username","purpose":"USERNAME","value":"[email protected]"},{"id":"password","label":"password","purpose":"PASSWORD","generate":true,"recipe":{"length":24,"characterSets":["LETTERS","DIGITS","SYMBOLS"]}}]}'
Patch a field
curl -X PATCH "https://api.sondahub.com/sandbox/1password-connect/v1/vaults/i7gwu4baaugmv7aapnir3saard/items/ckjrfeaaghkvt5bafsxnidaa1g" \
  -H "Authorization: Bearer sondahub-connect-token" \
  -H "Content-Type: application/json" \
  -d '[{"op":"replace","path":"/fields/port/value","value":"6432"},{"op":"add","path":"/tags/-","value":"pgbouncer"}]'
Your activity
curl "https://api.sondahub.com/sandbox/1password-connect/v1/activity" \
  -H "Authorization: Bearer sondahub-connect-token"

From the shell, keep the token yourself: curl -i shows X-Sondahub-Session; send it back with -H "X-Sondahub-Session: …". How sessions work.

The seed vaults

VaultWhat’s in it
Production
i7gwu4baaugmv7aapnir3saard
Credentials for the production systems: Orders database (database), Stripe (api credential), Admin console (login), Deploy key (ssh key)
Staging
3prff0aas9wgghaao2pp93aazq
Everything the staging environment reads: Staging database (database), SendGrid (api credential), Feature flags (secure note)
Shared
5ukjr0bacvgdjdbam5p4j1banq
Office and vendor access for the whole team: Office Wi-Fi (wireless router), Vendor portal (login), TLS certificate (document), Old FTP server (server, archived)

Items take any of the 22 categories, with fields (STRING, CONCEALED, EMAIL, URL, OTP, DATE, MENU…), purposes (USERNAME, PASSWORD, NOTES), sections, URLs and tags. A field with generate: true gets a password from its recipe — length 1 to 64, LETTERS, DIGITS, SYMBOLS, excluded characters — and its entropy. Every write moves the item’s version and the vault’s content version.

Every value in the seed is fake and made up when the site is built. What you write is kept in your own session token and nowhere else — but this is a public playground: never send it a real secret. Not affiliated with, or endorsed by, 1Password.

What it answers

GET/v1/vaultsAnd /v1/vaults/{id}; filter: name eq "…".
GET/v1/vaults/{vault}/itemsFilter: title eq "…", tag eq "…", co, sw, and, or. POST to create.
GET/v1/vaults/{vault}/items/{item}And PUT to replace, PATCH (JSON Patch), DELETE.
GET/v1/vaults/{vault}/items/{item}/filesAnd /files/{file}, /files/{file}/content; inline_files=true.
GET/v1/activityAnd /heartbeat, /health, /metrics.

All under /sandbox/1password-connect. Errors are Connect’s: {"status", "message"}.

Questions

Is this 1Password?

No — an independent imitation of the 1Password Connect server’s API for testing, not affiliated with or endorsed by 1Password. No account is involved and nothing is end-to-end encrypted: it answers the API a Connect server answers your apps.

Will the Connect SDKs work against it?

Yes, with the Connect host set to https://api.sondahub.com/sandbox/1password-connect. The Python set-up on this page was run against the sandbox with connect-sdk-python: vaults by name, items by title and id, a one-time-password field’s code, creating an item with a generated password, replacing it, files and their content, and deleting. The op CLI line uses its documented Connect variables.

What about service accounts and the newer SDKs?

The 1Password SDKs built on service accounts talk to 1Password’s own servers with end-to-end encryption, not to an HTTP API another server can stand in for — so they can’t be pointed here. Connect is the API you self-host for servers and pipelines, and that is the one modelled.

Are the one-time passwords real?

The codes are: a field of type OTP holding an otpauth:// URI (or a base32 secret) answers with the current six-digit code in totp, computed per RFC 6238 — your authenticator app would show the same code for the same secret.

What is not modelled?

Uploading files (Connect doesn’t either), item history, watchtower, sharing, and vault permissions per token: any token sees every vault. The activity log lists the writes your session made.