II.
Page JSON
Structured · livepage:docs-user-guide-private-install
Installing `@fabricstack/*` packages from the private registry json
Inspect the normalized record payload exactly as the atlas UI reads it.
{
"id": "page:docs-user-guide-private-install",
"_kind": "Page",
"_file": "wiki/docs/user-guide/private-install.md",
"_cluster": "wiki",
"attributes": {
"nodeKind": "Page",
"sourcePath": "docs/user-guide/private-install.md",
"sourceKind": "repo-docs",
"title": "Installing `@fabricstack/*` packages from the private registry",
"displayName": "Installing `@fabricstack/*` packages from the private registry",
"slug": "docs/user-guide/private-install",
"articlePath": "wiki/docs/user-guide/private-install.md",
"article": "\n[Docs](./index.md) › Private install (Artifact Registry npm)\n\n# Installing `@fabricstack/*` packages from the private registry\n\nFabric's npm packages are private. They publish only to the GCP Artifact Registry npm repository `fabric-npm` in project `boot-464019` (region `us-central1`), never to the public npm registry (decision D19; `docs/specs/platform-gaps/15-private-isolation-rename.md` §4). To install them you need two things:\n\n1. **Scope routing** — the committed root `.npmrc` already maps the `@fabricstack` scope to the registry. You do not add anything to it.\n2. **A short-lived credential** — an OAuth access token for your Google identity (or, in CI, for the deployer service account), written into *your user-level* `~/.npmrc` by the `google-artifactregistry-auth` helper.\n\nRegistry URL: `https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/`\n\n## The two `.npmrc` files (read this first)\n\n| File | Committed? | Contains | Who writes it |\n|---|---|---|---|\n| `<repo>/.npmrc` | yes | `@fabricstack:registry=https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/` (plus workspace settings) | maintainers, by pull request |\n| `~/.npmrc` (your home directory) | never | `//us-central1-npm.pkg.dev/boot-464019/fabric-npm/:_authToken=<token>` | `google-artifactregistry-auth`, on every refresh |\n\nCredentials go to the **user** npmrc only. The repository `.npmrc` must never gain an `_authToken`, `_password` or `token=` line; CI (`.github/workflows/ar-smoke.yml`) and the public-push guard both check it. If you ever see a credential in the repo file, remove it and rotate the token.\n\n## Developer setup\n\nPrerequisites: `gcloud` CLI installed, Node.js 22 with npm 10, and `roles/artifactregistry.reader` on `fabric-npm` for your Google account (ask a maintainer; the binding is per repository, not per project).\n\n### 1. Sign in to Google Cloud\n\n```bash\ngcloud auth login\n```\n\nThis signs in the `gcloud` CLI itself. The helper below can use that sign-in directly. If you prefer Application Default Credentials (the same mechanism client libraries use), run this instead or in addition:\n\n```bash\ngcloud auth application-default login\n```\n\nEither sign-in works; ADC is the one to use on a machine where several tools share Google credentials.\n\n### 2. Refresh the registry credential into your user npmrc\n\nFrom the repository root (the `--repo-config` file is the committed `.npmrc`, which tells the helper which `pkg.dev` registries you use):\n\n```bash\nnpx google-artifactregistry-auth --repo-config=.npmrc --credential-config=~/.npmrc\n```\n\nWhat this does: reads the registries from `.npmrc`, obtains an access token for your Google identity (from `gcloud auth login`, ADC, or `GOOGLE_APPLICATION_CREDENTIALS`), and writes `//us-central1-npm.pkg.dev/boot-464019/fabric-npm/:_authToken=...` into `~/.npmrc`. It does not modify the repository `.npmrc`.\n\nOn Windows PowerShell, `~` is not expanded inside an argument; spell the path out:\n\n```powershell\nnpx google-artifactregistry-auth --repo-config=.npmrc --credential-config=\"$HOME/.npmrc\"\n```\n\n### 3. Install\n\n```bash\nnpm install @fabricstack/smoke\nnode -e \"console.log(require('@fabricstack/smoke'))\"\n# { ok: true }\n```\n\n`@fabricstack/smoke` is the throwaway rehearsal package published by the smoke workflow; any `@fabricstack/*` package installs the same way. Outside the repository, put the single scope-routing line in the consuming project's `.npmrc` (or pass `--registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/` for a one-off) and run step 2 with `--repo-config` pointing at that file.\n\nConfirm what you are talking to:\n\n```bash\nnpm ping --registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/\nnpm view @fabricstack/smoke --registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/\n```\n\n## CI setup (GitHub Actions)\n\nCI never holds a long-lived registry credential. A job authenticates to GCP through Workload Identity Federation with the existing organization variables, then runs the same helper. The reference implementation is `.github/workflows/ar-smoke.yml`; the essential steps:\n\n```yaml\npermissions:\n contents: read\n id-token: write\n\nsteps:\n - uses: actions/checkout@v6\n - uses: actions/setup-node@v6\n with:\n node-version: 22\n - name: Authenticate to GCP (Workload Identity Federation)\n uses: google-github-actions/auth@v2\n with:\n workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }}\n service_account: ${{ vars.GCP_SERVICE_ACCOUNT }}\n - name: Refresh Artifact Registry npm credentials\n run: npx -y google-artifactregistry-auth --repo-config=.npmrc --credential-config=\"$HOME/.npmrc\"\n - run: npm ping --registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/\n```\n\nNotes:\n\n- `id-token: write` is what lets the runner mint the OIDC token that WIF exchanges; without it `google-github-actions/auth` fails before touching GCP.\n- Do not set `registry-url` on `actions/setup-node`: it writes its own `.npmrc` with a `NODE_AUTH_TOKEN` placeholder that conflicts with the helper.\n- The service account (`vars.GCP_SERVICE_ACCOUNT`, `github-deployer@boot-464019.iam.gserviceaccount.com`) holds `roles/artifactregistry.writer` on `fabric-npm` only, so it can publish as well as install. A job that only installs still uses the same steps.\n- `google-artifactregistry-auth` finds the WIF credential through `GOOGLE_APPLICATION_CREDENTIALS`, which `google-github-actions/auth@v2` exports by default.\n\n## Publishing (maintainers and the release train)\n\nEvery `@fabricstack/*` package sets `publishConfig.registry` to the registry URL, and `npm publish` honors that over any ambient config. Publication is CI's job alone: the private release train (`.github/workflows/publish-npm-private.yml`, WP-RN-07) publishes all 43 packages in dependency waves under a candidate dist-tag, validates the exact version from this registry, and only then moves the channel (`main` → `latest`, `staging` → `staging`, `develop` → `develop`) and creates the immutable `fabric/<branch>/v<version>` tag. Recovery from a tag, dist-tag repair and the dry-run commands are in [docs/RELEASE-RUNBOOK.md](../RELEASE-RUNBOOK.md); the model is in [docs/release-pipeline.md](../release-pipeline.md). Publishing anything under `@fabricstack` to the public npm registry is forbidden and guarded (spec 15 §4.3 G1–G6).\n\n## Troubleshooting\n\n| Symptom | Cause | Fix |\n|---|---|---|\n| `npm ERR! 403 Forbidden` on install or `npm view` | your Google account has no `roles/artifactregistry.reader` on `fabric-npm` | ask a maintainer to run `gcloud artifacts repositories add-iam-policy-binding fabric-npm --location=us-central1 --project=boot-464019 --member=user:<you> --role=roles/artifactregistry.reader` |\n| `npm ERR! 403 Forbidden` on `npm publish` | the identity has reader but not writer | publishing is CI's job; if you really need to, ask for `roles/artifactregistry.writer` on the repository |\n| `npm ERR! 401 Unauthorized` after it worked earlier | the access token expired (they live about one hour) | rerun step 2 (`npx google-artifactregistry-auth ...`) |\n| `npm ERR! 401` immediately, `~/.npmrc` has no `pkg.dev` line | the helper wrote to a different file, or `--credential-config` pointed at the repo file | rerun step 2 with an explicit absolute path for `--credential-config`; check `npm config get userconfig` |\n| `Could not load the default credentials` from the helper | no `gcloud auth login` / ADC on this machine | run step 1 |\n| `E404 Not Found` for `@fabricstack/<name>` | the scope is not routed (consuming project has no `.npmrc` line), so npm asked the public registry | add `@fabricstack:registry=https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/` to that project's `.npmrc` |\n| CI: `google-github-actions/auth` fails with a permission error | the workflow lacks `id-token: write`, or the repository is not in the service account's `roles/iam.workloadIdentityUser` binding (`attribute.repository/a5c-ai/<repo>`) | add the permission; ask an owner to review the binding (`gcloud iam service-accounts get-iam-policy github-deployer@boot-464019.iam.gserviceaccount.com`) |\n| a credential line appears in `<repo>/.npmrc` | someone ran the helper with `--credential-config=.npmrc` | delete the line, do not commit, rotate nothing (tokens expire) but recheck `git status` before every commit |\n\nProvisioning record (what exists in GCP, IAM policy, rollback): `docs/specs/platform-gaps/phase0/ar-provisioning.md`.\n",
"documents": []
},
"outgoingEdges": [],
"incomingEdges": [
{
"from": "page:docs-user-guide",
"to": "page:docs-user-guide-private-install",
"kind": "contains_page"
}
]
}