Skip to content

Create your first key

A vk_ key authenticates each request from a package manager. The key is scoped to one project, which lives inside one tenant. To mint a key, you need the tenant and the project first. See Tenants, projects, keys for the model.

This page walks the admin through creating all three for a new developer. There are two paths: the dashboard UI (easier, what most operators do) and the JSON admin API (scriptable, useful for CI provisioning).

  1. Sign in to the dashboard at https://vg-admin.<your-domain>/admin/ui with your admin credentials.
  2. Create a tenant (one per customer). Click New organization, enter a slug + display name. The slug is the URL-safe identifier that shows up in audit log queries and ingress routing.
  3. Create a project inside that tenant. Open the tenant detail page → Projects tab → New project. The project is typically one-per-repo or one-per-pipeline.
  4. Mint a key. Open the project detail page → API keys tab → New key. Upwarden surfaces the vk_… string once; copy it into your secret store immediately. You cannot retrieve it later — only revoke + re-mint.

If you’re provisioning programmatically (CI/CD seeding a new customer, scripted migration, etc.), the same three steps map to three POST calls under /api/v1/admin/. Authenticate every call with x-upwarden-admin-token: $ADMIN_API_TOKEN.

Terminal window
# 1. Create the tenant
curl -X POST "https://vg-admin.<your-domain>/api/v1/admin/orgs" \
-H "x-upwarden-admin-token: $ADMIN_API_TOKEN" \
-H "content-type: application/json" \
-d '{ "slug": "acme", "displayName": "Acme Inc." }'
# 2. Create the project under that tenant
curl -X POST "https://vg-admin.<your-domain>/api/v1/admin/orgs/acme/projects" \
-H "x-upwarden-admin-token: $ADMIN_API_TOKEN" \
-H "content-type: application/json" \
-d '{ "name": "frontend-build" }'
# → { "project": { "id": "…", "name": "frontend-build", … } }
# 3. Mint a key, bound to that project via project_id from step 2
curl -X POST "https://vg-admin.<your-domain>/api/v1/admin/orgs/acme/api-keys" \
-H "x-upwarden-admin-token: $ADMIN_API_TOKEN" \
-H "content-type: application/json" \
-d '{ "name": "ci-bot", "project_id": "<id from step 2>" }'
# → { "key": "vk_…", "id": "…", "last8": "…", "projectId": "…", "createdAt": "…" }

Hand the vk_… value to the developer; they wire it into the appropriate per-ecosystem config — .npmrc for npm/Bun/pnpm/Yarn, pip.conf for PyPI, ~/.cargo/config.toml for crates, etc. The Quickstart covers each ecosystem in two lines.

The key authenticates every install request from then on. The audit log stamps apiKeyId on every row, so when something goes wrong you can trace it to a specific key (and therefore a specific project and tenant) with one WHERE apiKeyId = ....

Keys don’t expire automatically. To rotate:

  1. Mint a new key (same project, new name).
  2. Roll the new key into the developer’s environment / secret store.
  3. Wait until the audit log shows the old key has zero traffic.
  4. Revoke the old key (dashboard → API keys → Revoke, or DELETE /api/v1/admin/orgs/<slug>/api-keys/<keyId>).

If a key leaks, skip the wait — revoke immediately and let the affected installs fail loudly until the developer rolls the new value in.