Spaces:
Running
Running
File size: 9,719 Bytes
a6a5d8e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | # A11oy UDS Payload
A single-command, signed, declaratively-deployable A11oy payload for
**Defense-Unicorns (UDS)** environments. Drop it into a UDS bundle and run one
`zarf package deploy` — no bespoke installer, no per-environment glue.
The build emits `dist/a11oy-uds/a11oy-uds-<version>.tar.zst` containing:
- Built `@a11oy/core` runtime (orchestration kernel)
- Built `@a11oy/connection` transport layer
- `MANIFEST.json` — per-file `sha256`, size, build timestamp, git SHA
- Either a `cosign` signature (`*.tar.zst.sig`) when `COSIGN_KEY` is set, or
an unsigned `*.tar.zst.sha256` sidecar otherwise
## Prerequisites
| Tool | Min version | Required for |
| -------- | ----------- | --------------------------------------- |
| `node` | 18+ | Manifest generation and verification |
| `tar` | any | Fallback packaging when `zarf` missing |
| `zstd` | any | Fallback packaging when `zarf` missing |
| `zarf` | 0.36+ | Native Zarf package creation/deploy |
| `cosign` | 2+ | Signing (only when `COSIGN_KEY` is set) |
The build is **strict by default**: it always runs `tsc` for both packages
and refuses to produce a payload if either build is empty. Setting
`A11OY_UDS_ALLOW_SOURCE_FALLBACK=1` permits dev-only source packaging
(records `sourcePackaged: true` in `MANIFEST.json`) — never use this for
release output.
If `zarf` is unavailable, the build still produces a deterministic
`.tar.zst`, **but writes it to a clearly-separated `dist/a11oy-uds-fallback/`
directory with a `.fallback.tar.zst` suffix.** That fallback is NOT a Zarf
package and cannot be deployed via `zarf package deploy`; it exists so CI
can still validate the manifest/sign path without the `zarf` binary.
If `cosign` is missing (or `COSIGN_KEY` is unset), the build writes an
unsigned `.sha256` sidecar instead of a `.sig`.
## Build
From the repo root:
```bash
pnpm --filter @workspace/a11oy-uds run build
# or, directly:
bash artifacts/a11oy-uds/scripts/build.sh
```
To sign the output:
```bash
export COSIGN_KEY=cosign.key # path to your cosign private key
bash artifacts/a11oy-uds/scripts/build.sh
```
Output:
- With `zarf`: `dist/a11oy-uds/a11oy-uds-<version>.tar.zst` (+ `.sig` or `.sha256`)
- Without `zarf` (dev only): `dist/a11oy-uds-fallback/a11oy-uds-<version>.fallback.tar.zst`
## Verify
The build runs `scripts/verify-manifest.mjs` automatically and refuses to
produce a tarball if any file's `sha256` does not round-trip. To re-verify on
demand (e.g. after unpacking):
```bash
pnpm --filter @workspace/a11oy-uds run verify
# or against an unpacked tarball:
node artifacts/a11oy-uds/scripts/verify-manifest.mjs /path/to/unpacked
```
If `cosign` was used to sign, verify the signature with the matching public
key:
```bash
cosign verify-blob \
--key cosign.pub \
--signature a11oy-uds-<version>.tar.zst.sig \
a11oy-uds-<version>.tar.zst
```
Otherwise verify the unsigned sidecar:
```bash
cd dist/a11oy-uds && sha256sum -c a11oy-uds-<version>.tar.zst.sha256
```
## Operator runbook
### Deploy
```bash
zarf package deploy a11oy-uds-<version>.tar.zst --confirm
```
This stages the three declared components (`a11oy-core`,
`a11oy-connection`, `a11oy-provenance`) under `/opt/a11oy/` on the target
node.
### Inspect
Before deploy (or any time after), list components, images, and metadata:
```bash
zarf package inspect a11oy-uds-<version>.tar.zst
```
This emits the parsed `zarf.yaml`, the SBOM (if produced by Zarf), and the
per-file sha256 manifest baked into the payload.
### Rollback
```bash
# Remove the deployed package by name (matches metadata.name in zarf.yaml):
zarf package remove a11oy-uds --confirm
# Then re-deploy the previous known-good tarball:
zarf package deploy a11oy-uds-<previous-version>.tar.zst --confirm
```
Because every release ships with a content-addressed `MANIFEST.json` and
either a cosign signature or sha256 sidecar, you can always confirm that the
tarball you're rolling back to is bit-for-bit the one you originally
released.
## Attestation chain (optional component)
The `a11oy-attestations` Zarf component (optional, off by default) ships
a second sidecar — `ATTESTATIONS.json` — alongside `MANIFEST.json`. Where
`MANIFEST.json` is a flat per-file sha256 manifest, `ATTESTATIONS.json`
is a hash-chained provenance record over the *built subjects*
(`a11oy-core`, `a11oy-connection`). It is what the top-level
`szl-mesh` UDS bundle references as
`optionalComponents: [a11oy-attestations]`, and it is what enables
**offline** verification — no registry round-trip, no transparency log.
### Format
```jsonc
{
"name": "a11oy-attestations",
"version": "0.1.0",
"gitSha": "abc1234",
"builtAt": "2026-05-26T00:00:00Z",
"hashAlgorithm": "sha256",
"manifestSha256": "<sha256 of MANIFEST.json bytes>",
"subjects": ["a11oy-core", "a11oy-connection"],
"chain": [
{
"index": 0,
"subject": "a11oy-core",
"fileCount": 42,
"totalBytes": 123456,
"subjectSha256": "<digest of canonical subject lines>",
"prevHash": "0000…0000", // 64 zeros — genesis
"entryHash": "<sha256 of link>"
},
{
"index": 1,
"subject": "a11oy-connection",
"fileCount": 17,
"totalBytes": 65432,
"subjectSha256": "<digest>",
"prevHash": "<chain[0].entryHash>",
"entryHash": "<sha256 of link>"
}
],
"head": "<chain[N-1].entryHash>"
}
```
The subject digest is `sha256` of the canonical line-stream
`"<relPath>\t<sha256>\t<size>\n"` for every `MANIFEST.json` file under
`<subject>/`, sorted by `relPath`. The link hash is
`sha256("<index>\n<subject>\n<subjectSha256>\n<prevHash>\n")`. `prevHash`
for `index = 0` is 64 zeros (genesis). The terminal `head` field is the
last link's `entryHash`, so a verifier only needs to trust `head` to
trust the whole chain.
This is a **hash chain only** — there is no cryptographic signature on
the chain itself. Signing is handled by the existing cosign sidecar at
the tarball level; signing the chain head is intentionally out of scope.
### Verify
The build runs the verifier automatically and refuses to produce a
tarball if any link is broken. To re-verify on demand:
```bash
pnpm --filter @workspace/a11oy-uds run verify:attestations
# or against an unpacked deploy target (MANIFEST.json + ATTESTATIONS.json
# side by side under /opt/a11oy/ once both components are deployed):
node artifacts/a11oy-uds/scripts/verify-attestations.mjs \
/opt/a11oy /opt/a11oy
```
### Opt in at deploy time
Because the component is `required: false` and `default: false`, a plain
`zarf package deploy` will skip it. Either opt in explicitly:
```bash
zarf package deploy a11oy-uds-<version>.tar.zst \
--components a11oy-core,a11oy-connection,a11oy-provenance,a11oy-attestations \
--confirm
```
…or deploy the parent `szl-mesh` UDS bundle, which lists
`a11oy-attestations` under `optionalComponents` for the `a11oy` package.
## Layout
```
artifacts/a11oy-uds/
├── README.md
├── package.json # @workspace/a11oy-uds (build + verify scripts)
├── zarf.yaml # Zarf v1 package definition
├── scripts/
│ ├── build.sh # End-to-end build + sign/sidecar pipeline
│ ├── write-manifest.mjs # Generates MANIFEST.json
│ └── verify-manifest.mjs # Re-hashes every file; fails on mismatch
└── build/ # (generated) staged payload + MANIFEST.json
```
Build output lives at `dist/a11oy-uds/` at the repo root.
## Registry
The intended release channel is a GitHub Release artifact plus an optional
GHCR/OCI mirror. Treat the GitHub Release assets and their sha256/cosign
sidecars as canonical unless a repository workflow named
`a11oy-uds-publish.yml` is present and green for the exact tag.
| Channel | Coordinates | Signed | When |
| ------- | ---------------------------------------------------- | ----------------------- | -------------------------- |
| release | GitHub Release assets (`*.tar.zst`, `.sha256`, `.sig`, `.pub`) | yes when `.sig` is attached | tagged UDS release |
| optional mirror | `oci://ghcr.io/szl-holdings/a11oy-uds:<version>` | only when a matching publish workflow is present and green | operator mirror |
| dev | local fallback tarball | unsigned unless `COSIGN_KEY` is set | CI/dev verification only |
Pull a release by name + version:
```bash
zarf package pull oci://ghcr.io/szl-holdings/a11oy-uds:0.1.0
zarf package deploy zarf-package-a11oy-uds-*.tar.zst --confirm
```
Verify the cosign signature (release channel only) against the published
digest:
```bash
cosign verify \
--certificate-identity-regexp 'https://github.com/szl-holdings/.+/\.github/workflows/a11oy-uds-publish\.yml@.+' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/szl-holdings/a11oy-uds:0.1.0
```
For pre-release testing, use a locally built payload or a GitHub Release asset.
Only use an OCI dev channel if the matching publish workflow exists in this
repository and reports success for the commit under review:
```bash
zarf package pull oci://ghcr.io/szl-holdings/a11oy-uds:dev
```
Release assets should attach the raw `*.tar.zst`, `.sig`, `.pub`, and `.sha256`
sidecars to the corresponding GitHub Release for air-gapped operators who
cannot reach an OCI registry.
## Out of scope
- Publishing to non-OCI registries (S3, Artifactory, etc.)
- Authoring Helm charts beyond what `zarf package create` consumes
- Deploy-time secrets management — UDS operators handle that out-of-band
|