OpsDev.nz helpers for resolving 1Password secrets with Service Account + CLI fallback.
Project description
op-opsdevnz
Resolve 1Password op:// secret references at runtime so automation code
stays secret-free. Resolution uses the official 1Password Service Account SDK
for CI, with a conditional fallback to the op CLI for local development —
and a strict security posture: credential principals never switch silently,
and errors never leak secret values, fragments, or references.
Maintained by OpsDev.nz, a platform engineering collective sponsored by StartMeUp.nz.
Features
- Resolve
op://references via the official Service Account SDK with a conditional CLI fallback for local workflows. - Explicit fallback policy: the CLI is used only when the SDK path is not configured. A configured-but-failing SDK is a hard error, so resolution never silently switches credential principals.
- Sanitized errors: failure output never includes secret values, fragments,
op://references, or raw subprocess/SDK diagnostics. - Rich error handling plus an API that can return the secret value and which resolver was used.
- Environment override helpers for CI sandboxes/tests.
- OctoDNS hook (
op_opsdevnz.octodns_hooks.resolve) for the Metaname provider. - Small CLI (
op-opsdevnz resolve …) that follows the same resolution semantics asresolve_secret(). Output is an opaque mask by default;--no-maskprints the resolved value.
Installation
# latest release from PyPI
pip install op-opsdevnz
# or install straight from GitHub if you need main branch changes
pip install git+https://github.com/startmeup-nz/op-opsdevnz.git
Requires Python 3.12+ and one of:
- CI / automation:
OP_SERVICE_ACCOUNT_TOKENset (a 1Password Service Account) - Workstations: the 1Password CLI
installed and signed in (
op signin)
Usage
from op_opsdevnz.onepassword import resolve_secret
result = resolve_secret(
secret_ref_env="METANAME_API_TOKEN_REF",
env_override="METANAME_API_TOKEN",
)
print(result.value, result.source) # -> ('***', 'sdk' | 'cli' | 'env')
The canonical import package is op_opsdevnz (matching the op-opsdevnz
distribution name). The legacy opsdevnz package was removed in 0.2.0.
CLI equivalent:
op-opsdevnz resolve --ref "op://Vault/Item/Field" --show-source
op-opsdevnz resolve --ref-env METANAME_API_TOKEN_REF --env-override METANAME_API_TOKEN
op-opsdevnz resolve --ref "op://Vault/Item/Field" --no-mask # print the value
Async Usage
resolve_secret() and get_secret() are synchronous and must not be called
from within a running event loop (they bridge the SDK with asyncio.run()
and raise a clear error there). Async callers use the async API directly:
from op_opsdevnz.onepassword_sdk import resolve_secret_async
value = await resolve_secret_async("op://Vault/Item/Field")
Secret Reference Files
For per-environment reference files (references only — no secret values, safe to commit):
from op_opsdevnz.env import load_refs
load_refs("staging") # loads .env.refs.staging into the environment
Fallback Policy
Resolution follows a strict rule (see docs/design/fallback-policy.md):
- Default (SDK first): with
OP_SERVICE_ACCOUNT_TOKENset, the Service Account SDK resolves the reference. Any SDK failure — authentication, authorization, resolution, rate limit — raisesSdkAuthErrorand the CLI is not tried. - Not configured: without a token (or without the SDK installed),
SdkNotConfiguredErroris raised internally and resolution falls back to the locally authenticatedopCLI. prefer_cli=True: workstations can opt into CLI-first resolution; the SDK remains the fallback so CI/service-account flows keep working.
Error classes SdkNotConfiguredError and SdkAuthError subclass
SecretError, so existing except SecretError handlers keep working.
OctoDNS Hook
Set the resolver environment variable so the OctoDNS Metaname provider can load the helper automatically:
export OCTODNS_METANAME_SECRET_RESOLVER="op_opsdevnz.octodns_hooks:resolve"
The hook resolves CLI-first on workstations (no token) and SDK-first when
OP_SERVICE_ACCOUNT_TOKEN is set, matching the fallback policy above.
Development
uv sync --extra dev
uv run ruff check src tests
uv run mypy src
uv run python -m pytest tests/ --cov
See CONTRIBUTING.md for the full workflow and RELEASING.md for publishing instructions.
License
Apache-2.0 © OpsDev.nz
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file op_opsdevnz-0.2.0.tar.gz.
File metadata
- Download URL: op_opsdevnz-0.2.0.tar.gz
- Upload date:
- Size: 18.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6da20f6a318553102526e58873f970b2c7ed963132bdb07050ab8afbc992a60
|
|
| MD5 |
b09fdfdd76fcf7a49c7690c3351b67c0
|
|
| BLAKE2b-256 |
d054f68c7fcef54488b5db88ad70be094adcee991c21628f97fee19378e48238
|
Provenance
The following attestation bundles were made for op_opsdevnz-0.2.0.tar.gz:
Publisher:
publish.yml on startmeup-nz/op-opsdevnz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
op_opsdevnz-0.2.0.tar.gz -
Subject digest:
d6da20f6a318553102526e58873f970b2c7ed963132bdb07050ab8afbc992a60 - Sigstore transparency entry: 2338198823
- Sigstore integration time:
-
Permalink:
startmeup-nz/op-opsdevnz@e6929a8f7f13232455d246c9ff22e2db1d82eb25 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/startmeup-nz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e6929a8f7f13232455d246c9ff22e2db1d82eb25 -
Trigger Event:
push
-
Statement type:
File details
Details for the file op_opsdevnz-0.2.0-py3-none-any.whl.
File metadata
- Download URL: op_opsdevnz-0.2.0-py3-none-any.whl
- Upload date:
- Size: 14.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f5d6aa1633b11d963dbe1367212f30aeb3de011fa108219ab26524953ab10f4
|
|
| MD5 |
ec1f90dd20b05a48531aa9c0c8d6cd0a
|
|
| BLAKE2b-256 |
552f41fad233ee3be377f1bcdf8429aa07bad31db8938f931e8d77ef41854016
|
Provenance
The following attestation bundles were made for op_opsdevnz-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on startmeup-nz/op-opsdevnz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
op_opsdevnz-0.2.0-py3-none-any.whl -
Subject digest:
6f5d6aa1633b11d963dbe1367212f30aeb3de011fa108219ab26524953ab10f4 - Sigstore transparency entry: 2338198829
- Sigstore integration time:
-
Permalink:
startmeup-nz/op-opsdevnz@e6929a8f7f13232455d246c9ff22e2db1d82eb25 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/startmeup-nz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e6929a8f7f13232455d246c9ff22e2db1d82eb25 -
Trigger Event:
push
-
Statement type: