# ocx_sdk

*module*

Python SDK for [OCX](https://github.com/ocx-sh/ocx).

`ocx-sdk` drives the ocx binary rather than reimplementing it: ocx owns
resolution, verification, and the identifier grammar, and this package gives
you typed, CWD-independent handles over the commands it exposes.

```python
from ocx_sdk import Ocx, bootstrap

ocx = Ocx(exe=bootstrap.ensure())
project = ocx.project("/srv/build")
project.pull()
project.exec(["task", "verify"])
```

**This module is the API.** Everything listed in `__all__` is the stable
surface; every other module is underscored and package-private, and the one
public submodule is `ocx_sdk.bootstrap`. Reaching into an underscored path
means the next release may move it without notice — pre-1.0, breaking
changes ship without shims.

Start at `Ocx` for the runtime API and `bootstrap.ensure` for provisioning.

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/__init__.py#L1-L1)

## ocx_sdk.PackageCommands

*class* · *dataclass*

```python
class PackageCommands
```

Re-exported from: `ocx_sdk._client`

The `ocx package` command group — machine tier.

Package operations act on the `$OCX_HOME` store and its candidate and
current symlinks. They take no project path and are CWD-independent by
construction; a path appears only where the CLI itself takes one.

Every method is multi-identifier native, mirroring the CLI's `PKG...`
with one shared resolution.

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_client.py#L1470-L3367)

### ocx_sdk.PackageCommands.deps

*method*

```python
def deps(*refs: PackageLike, platform: str | None = None, private: bool = False, why: PackageLike | None = None, depth: int | None = None, timeout: MaybeTimeout = UNSET, retry: MaybeRetry = UNSET) -> DepsReport
```

Show the dependency tree of installed packages.

**Parameters**

- `*refs` (`PackageLike`) (default: `()`) — Package identifiers.
- `platform` (`str | None`) (default: `None`) — The platform to resolve against.
- `private` (`bool`) (default: `False`) — Include the private, self-only edges — ocx's `--self`. Generated launchers pass it; a consumer needs it only when building a launcher equivalent.
- `why` (`PackageLike | None`) (default: `None`) — Explain why this dependency is pulled in. Matched by registry and repository; the tag is ignored.
- `depth` (`int | None`) (default: `None`) — Limit the tree depth. `None` is unlimited.
- `timeout` (`MaybeTimeout`) (default: `UNSET`) — Seconds per attempt. Omitted takes the config's.
- `retry` (`MaybeRetry`) (default: `UNSET`) — Retry policy. `None` opts out; omitted takes the config's.

**Returns**

- (`DepsReport`) — One root per requested package.

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_client.py#L1948-L1986)

### ocx_sdk.PackageCommands.verify

*method*

```python
def verify(ref: PackageLike, *, platform: str | None = None, certificate_identity: str | None = None, certificate_oidc_issuer: str | None = None, key: str | None = None, signature_format: SignatureFormat | None = None, rekor_url: str | None = None, attestation: bool = False, predicate_type: str | None = None, allow_unlogged_signature: bool = False, no_cache: bool = False, sigstore_trusted_root: str | Path | None = None, timeout: MaybeTimeout = UNSET, retry: MaybeRetry = UNSET) -> VerificationReport
```

Verify a package reference's signature or attestation (C-012).

A read — not mutating, and keeps the normal retry default (D5).

Keyless verification needs the identity pair: cosign 2.0 made
`--certificate-identity` and `--certificate-oidc-issuer`
hard-required together, because without both a signature from
*any* Fulcio-certified identity passes (D3). Neither is usable
alongside `key`.

**Parameters**

- `ref` (`PackageLike`) — The package reference to verify.
- `platform` (`str | None`) (default: `None`) — Verify one platform's manifest.
- `certificate_identity` (`str | None`) (default: `None`) — The pinned keyless identity. Required together with `certificate_oidc_issuer` for keyless verification.
- `certificate_oidc_issuer` (`str | None`) (default: `None`) — The pinned keyless OIDC issuer. Required together with `certificate_identity`.
- `key` (`str | None`) (default: `None`) — A key reference, for key-based verification.
- `signature_format` (`SignatureFormat | None`) (default: `None`) — Restrict to one signature format. `'both'` is write-side only — it names two shapes, and a result cannot say "either of these satisfied me".
- `rekor_url` (`str | None`) (default: `None`) — A non-default Rekor instance.
- `attestation` (`bool`) (default: `False`) — Verify an attestation instead of a signature.
- `predicate_type` (`str | None`) (default: `None`) — Restrict attestation verification to this predicate type. Requires `attestation=True`.
- `allow_unlogged_signature` (`bool`) (default: `False`) — Accept a signature with no transparency log entry.
- `no_cache` (`bool`) (default: `False`) — Skip ocx's verification cache.
- `sigstore_trusted_root` (`str | Path | None`) (default: `None`) — A non-default Sigstore trusted root bundle.
- `timeout` (`MaybeTimeout`) (default: `UNSET`) — Seconds per attempt. Omitted takes the config's.
- `retry` (`MaybeRetry`) (default: `UNSET`) — Retry policy. `None` opts out; omitted takes the config's.

**Returns**

- (`VerificationReport`) — The verified subject, identity, and matching signatures.

**Raises**

- `ValueError` — Only one of `certificate_identity`/
`certificate_oidc_issuer` was given, either was given
alongside `key`, `predicate_type` was given without
`attestation=True`, or `signature_format` was `'both'`.
- `OcxProcessError` — The signature did not verify — this command's
main outcome, not an edge case. `DataError` (65) for a
signature or certificate chain that did not hold up,
`PermissionDeniedError` (77) for an identity or issuer that
did not match, `NotFoundError` (79) when nothing is signed at
all, and `TransparencyLogUnavailableError` (83) when Rekor is
unreachable.

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_client.py#L2733-L2828)
