# CodeArtifact Provisioning — Status + Fallback (REQ-323, CAP-035) > Phase P1 (cli-substrate), milestone v1.28. Owner: backend-engineer. > This document records the CodeArtifact provisioning check outcome for > the `nova-cli` wheel + Lambda layer publish pipeline (REQ-323), the > required IAM grants, and the fallback wheel-index mode the publish > workflow supports when CodeArtifact is not yet provisioned. ## 1. Provisioning check (best-effort, P1 Wave 4 gate) **Target account:** `581513795199` (the Nova platform account). **Attempted commands:** ```bash aws codeartifact list-domains --region us-east-1 aws codeartifact describe-repository --domain nova --repository nova-pypi --region us-east-1 aws codeartifact list-repositories --domain nova --region us-east-1 ``` **Result:** the check could not complete — no AWS credentials were available in the P1 execute environment (`Unable to locate credentials. You can configure credentials by running `aws configure`.`). This is the "fail gracefully" path documented in the task spec: provisioning is **not attempted** from this environment because the required IAM grants are not confirmed for the execute principal. **Classification:** P1 blocker for the CodeArtifact mode of the publish workflow's wheel-upload step. The workflow ships with a fallback mode (see §3) so the pipeline is not blocked on CodeArtifact provisioning — it can publish to a private wheel index instead. ## 2. Required IAM grants (for a follow-up provisioning task) To provision + use CodeArtifact as the wheel index, the principal that runs the publish workflow (OIDC role `nova-publish-*` or the spike runner) needs the following grants in account `581513795199`: | Action | Scope (example) | Purpose | | --- | --- | --- | | `codeartifact:CreateDomain` | `arn:aws:codeartifact:us-east-1:581513795199:domain/nova` | create the `nova` domain | | `codeartifact:CreateRepository` | `arn:aws:codeartifact:us-east-1:581513795199:repository/nova/*` | create `nova-pypi` (pypi-format) | | `codeartifact:GetRepositoryEndpoint` | `arn:aws:codeartifact:us-east-1:581513795199:repository/nova/nova-pypi` | get the twine/pip endpoint | | `codeartifact:GetAuthorizationToken` | `arn:aws:codeartifact:us-east-1:581513795199:domain/nova/*` | mint short-lived upload token | | `codeartifact:ReadFromRepository` | `arn:aws:codeartifact:us-east-1:581513795199:repository/nova/nova-pypi` | pip install (consumers + the composite action) | | `codeartifact:PublishPackageToRepository` | `arn:aws:codeartifact:us-east-1:581513795199:repository/nova/nova-pypi` | twine upload | | `ssm:PutParameter` / `ssm:GetParameter` | `arn:aws:ssm:us-east-1:581513795199:parameter/nova/layer/*` | CAP-035 version↔ARN mapping | | `lambda:PublishLayerVersion` | `arn:aws:lambda:us-east-1:581513795199:layer:nova-cli` | Lambda layer publish | | `iam:CreateRole` / `iam:PassRole` (already held) | — | only if a dedicated publish OIDC role must be created | The domain + repository to provision: - **Domain:** `nova` - **Repository:** `nova-pypi` (format: `pypi`) - **Endpoint (twine/pip):** `https://nova-581513795199.d.codeartifact.us-east-1.amazonaws.com/pypi/nova-pypi/` Once provisioned, set the repository secret `NOVA_CODEARTIFACT_DOMAIN=nova` on both forges and the publish workflow + composite action will switch to CodeArtifact mode automatically (see §3). ## 3. Fallback: private wheel index (`NOVA_WHEEL_INDEX`) Both the publish workflow (`.github/workflows/publish.yml` and its byte-identical mirror on the dev forge) and the composite action (`.github/actions/nova-cli/action.yml`) support a **fallback mode** that does not require CodeArtifact. The selection is env/secret driven: | Mode | Trigger | Upload target | Install source | | --- | --- | --- | --- | | **CodeArtifact** | `NOVA_CODEARTIFACT_DOMAIN` env/secret is set | `aws codeartifact login --tool twine` → twine uploads to the CodeArtifact pypi endpoint | `aws codeartifact login --tool pip` → `pip install nova==` | | **Fallback index** | `NOVA_CODEARTIFACT_DOMAIN` unset; `TWINE_REPOSITORY_URL` + `TWINE_USERNAME` + `TWINE_PASSWORD` set | `twine upload` to `TWINE_REPOSITORY_URL` | `pip install --index-url $NOVA_WHEEL_INDEX nova==` | The fallback index can be any PEP 503-compliant simple index — e.g. a private package registry hosted on the dev forge, a self-hosted `pypiserver`, or a static S3-backed index. The workflow does not hardcode the index URL; it is supplied via the `NOVA_WHEEL_INDEX` env var (for consumers / the composite action) and `TWINE_REPOSITORY_URL` (for the publish step). This keeps the forge/registry choice deployment-specific and avoids baking any single hostname into the synced workflow files. ### 3.1 Fallback index shape (when self-hosted) A minimal PEP 503 simple index served from a private registry is sufficient. The only required layout per package: ``` /nova/ index.html # links to each version's page /nova--py3-none-any.whl # the wheel (publish workflow uploads this) ``` The publish workflow uploads `dist/nova--*.whl` via `twine upload` to `TWINE_REPOSITORY_URL`; consumers install via `pip install --index-url "$NOVA_WHEEL_INDEX" nova==`. ## 4. CAP-035 invariant (unaffected by the index choice) Regardless of which wheel index is used, the Lambda layer ARN ↔ wheel version mapping is recorded in SSM and is the source of truth for CAP-035: ``` /nova/layer/nova-cli/version = ":" ``` e.g. `1.14.0:arn:aws:lambda:us-east-1:581513795199:layer:nova-cli:3`. The publish workflow writes this parameter atomically after both the wheel upload and the layer publish succeed; if either fails the job fails (merge blocked, REQ-323 AC). ## 5. Open follow-ups 1. Provision CodeArtifact domain `nova` + repository `nova-pypi` in `581513795199` once the `codeartifact:*` grants in §2 are attached to the publish OIDC role. Update this document with the confirmed ARN + endpoint. 2. Set the `NOVA_CODEARTIFACT_DOMAIN` repository secret on both forges to switch the publish workflow + composite action from fallback-index mode to CodeArtifact mode. 3. Until §1 is done, the fallback index must be provisioned out of band and its URL exposed to consumers via the `NOVA_WHEEL_INDEX` env var (and to the publish workflow via the `TWINE_*` secrets).