- integrations
- Python
- Errors & credentials: PackageRef: carried, never parsed
Errors & credentials: PackageRef: carried, never parsed
Part 2 of 2 of Errors & credentials.
PackageRef: carried, never parsed
Section titled “PackageRef: carried, never parsed”ocx owns the package-identifier grammar. PackageRef
stores whatever identifier string it was given and hands it back byte for
byte — the SDK never re-derives or re-validates the grammar itself:
from ocx_sdk import PackageRef
ref = PackageRef("ocx.sh/astral-sh/uv:0.9.7")carried_forward = PackageRef("ocx.sh/astral-sh/uv:0.9.7", metadata={"source": "lock"})
assert str(ref) == "ocx.sh/astral-sh/uv:0.9.7"assert ref == carried_forward # identity is the identifier alone; metadata is decorationIdentity is the identifier string alone — metadata is whatever context
came along with the ref from the JSON row that produced it, so two refs to
the same package parsed out of two different commands must compare equal
even when their metadata differs. Any parameter typed PackageLike accepts
either a bare str or a PackageRef and coerces with str().
Credential handling
Section titled “Credential handling”One vocabulary for both bootstrap and runtime auth:
BasicAuth(user, password) and
BearerAuth(token) — None
elsewhere means anonymous, matching ocx’s own type set. Their secret fields
are field(repr=False), with a hand-written __repr__ that masks the
value — the dataclass-generated repr would otherwise leak into logs,
tracebacks, and pytest diffs:
from ocx_sdk import BasicAuth, BearerAuth
assert repr(BasicAuth("ci", "hunter2")) == "BasicAuth(user='ci', password=***)"assert repr(BearerAuth("ghp_secret")) == "BearerAuth(token=***)"Beyond the repr mask, every secret value the SDK composed into a spawn
environment is exact-string-redacted from captured stderr, on_log lines,
logged argv, and exception text — the choke point is
_env.build_spawn_env(), which
returns the finished environment paired with a redact callable that
_process applies to every outbound surface before it leaves the SDK. A
caller who puts a token into invoke’s raw argv gets it scrubbed the same
way, even though doing so is documented against.
One caveat the redaction can’t reach: at log_level="trace", ocx itself may
print secrets it holds that never passed through the SDK’s own composition
— the scrub only catches values the SDK was given.
Blast radius under exec
Section titled “Blast radius under exec”ocx does not scrub non-forwarded environment variables from a spawned
child — so a tool started through
Project.exec or
package.exec
inherits OCX_AUTH_*, whatever set it to (ambient environment or explicit
OcxConfig.auth). This is pinned by a contract test against the real
binary specifically so an upstream change to that behavior breaks loudly
rather than silently. The credential-free pattern: authenticate for the
pull(), then run the build step through a config with credentials
cleared —
# illustrative: needs a real Project handle.project.pull() # needs the tokenproject.with_config(auth={}).exec(["task", "build"]) # the build step doesn't see it— covered in full, with the rest of the hermetic-CI threat model, in Hermetic CI.
Persistent credentials
Section titled “Persistent credentials”Ocx.login writes credentials
through ocx’s own store — the token travels on stdin via
--password-stdin, never in argv, and is redacted for the call’s duration
like any other secret. OcxConfig.docker_config points ocx at an isolated
credential store directory; keep it 0700, since it holds registry
credentials on disk.