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
curl "https://api.sondahub.com/sandbox/1password-connect/v1/vaults" \ -H "Authorization: Bearer sondahub-connect-token"
curl "https://api.sondahub.com/sandbox/1password-connect/v1/vaults/i7gwu4baaugmv7aapnir3saard/items" \ -H "Authorization: Bearer sondahub-connect-token"
curl "https://api.sondahub.com/sandbox/1password-connect/v1/vaults/i7gwu4baaugmv7aapnir3saard/items/p7dw1zbar0s1wdaay8xkz7aaei" \ -H "Authorization: Bearer sondahub-connect-token"
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"
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"]}}]}'
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"}]'
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
| Vault | What’s in it |
|---|---|
Productioni7gwu4baaugmv7aapnir3saard | Credentials for the production systems: Orders database (database), Stripe (api credential), Admin console (login), Deploy key (ssh key) |
Staging3prff0aas9wgghaao2pp93aazq | Everything the staging environment reads: Staging database (database), SendGrid (api credential), Feature flags (secure note) |
Shared5ukjr0bacvgdjdbam5p4j1banq | 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
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.