Getting started (development)
How to run the protostar registry locally and sign in to it with the CLI. This covers the full development loop: prerequisites, the one-time GitHub OAuth setup, running the stack under .NET Aspire, and authenticating end to end.
The registry is the service users will sync their skills to; the protostar CLI is a separate,
disconnected client. (Sync is not built yet — today the working end-to-end path is authentication.)
You can run the registry on its own, but to exercise sign-in you will use both.
Prerequisites
- .NET 10 SDK
- A container runtime (Docker or Podman) — Aspire starts Postgres in a container.
- The ASP.NET Core HTTPS dev certificate, trusted once:
The API is served over HTTPS in every environment (OpenIddict rejects plain HTTP), so this is required, not optional.dotnet dev-certs https --trust
One-time setup: GitHub OAuth app
Sign-in is federated to GitHub, so you need a GitHub OAuth app. Create it in the
voidprojectssoftware org (not your personal account) so the whole team can manage it.
- Go to
https://github.com/organizations/voidprojectssoftware/settings/applications/new(or: org → Settings → Developer settings → OAuth Apps → New OAuth App). You must be an org owner. Pick OAuth App, not GitHub App — the registry uses the OAuth App flow. - Fill in:
- Application name:
protostar registry (dev) - Homepage URL:
https://github.com/voidprojectssoftware/protostar-registry - Authorization callback URL:
https://localhost:7443/signin-githubThe API is pinned tohttps://localhost:7443in dev (see below), so this callback stays stable across runs./signin-githubis the GitHub handler's default callback path.
- Application name:
- Create it, then Generate a new client secret and copy the secret immediately (shown once).
- Store the credentials in the AppHost's user-secrets (they stay on your machine, never in the repo):
cd src/Protostar.Registry.AppHostdotnet user-secrets set "Parameters:GitHubClientId" "<client id>"dotnet user-secrets set "Parameters:GitHubClientSecret" "<client secret>"
Without these, the stack still boots (the AppHost defaults the values to placeholder), but the
GitHub leg of sign-in will fail. Use a separate OAuth app per environment — make another one with
the production callback when you deploy, rather than reusing this dev app.
voidprojectssoftware org?Creating the app in the org is preferred so the whole team can manage it, but it
is not required to get sign-in working locally. If you cannot create an org app,
make the OAuth app under your own GitHub account (the
new-OAuth-App page) with the exact
same callback https://localhost:7443/signin-github. It works identically for
local development.
Run the registry
dotnet run --project src/Protostar.Registry.AppHost
This brings up Postgres and the API together and prints the Aspire dashboard URL. In the
dashboard you will see two resources, postgres and api. The API:
- is pinned to
https://localhost:7443(a stable, non-proxied port — this is what--registryand the GitHub callback point at); - applies EF Core migrations and seeds the
protostar-cliOAuth client automatically in Development; - exposes named links in the dashboard: API reference (Scalar) at
/scalar/v1, OpenAPI document at/openapi/v1.json, Service metadata at/v1/meta, OpenID configuration, and Health checks.
The dashboard runs on its own port (e.g.
https://localhost:17254). That is not the API — point clients at theapiresource URL (https://localhost:7443), not the dashboard.
img/aspire-dashboard.pngThe Aspire dashboard on first run, showing the postgres and api resources and
the named API links. Drop the image into docs/img/ and replace this admonition
with: 
Quick check:
curl -k https://localhost:7443/v1/meta
# {"service":"protostar-registry","version":"0.1.0-alpha.0.N","apiMajors":[1]}
Sign in with the CLI
Build the CLI from source (see CLI → Build from source), then:
protostar auth login # defaults to https://localhost:7443
protostar auth login --provider github # skip the chooser, go straight to GitHub
protostar auth status
protostar auth logout
auth login opens your browser to the registry's sign-in chooser, you pick GitHub (or --provider
skips the chooser), the registry federates to GitHub, and the resulting tokens are stored in
~/.protostar/credentials.json (owner-only permissions; override with PROTOSTAR_CONFIG_DIR).
Point at a different registry with --registry <url> or PROTOSTAR_REGISTRY_URL.
The CLI checks API compatibility (/v1/meta) on connect and refuses an unsupported major.
Tests
dotnet test
Registry integration tests use WebApplicationFactory and run database-free (they cover the API
surface, the sign-in chooser, and the OIDC discovery document). Database-backed acceptance scenarios
live in the CLI repo's Reqnroll suite.
Database and migrations
The schema is EF Core (RegistryDbContext) plus OpenIddict's tables. Migrations apply automatically
on startup in Development only. In production they are not auto-applied — they are run as an
explicit deploy step (typically dotnet ef database update, or a generated migration bundle, run by
your deploy pipeline before the new image serves traffic). Keeping production manual avoids a racing
container applying a migration mid-rollout.
Migration commands use the EF Core CLI tool. Install it once if you do not have it:
dotnet tool install --global dotnet-ef
To add a migration after changing the model:
dotnet ef migrations add <Name> --project src/Protostar.Registry.Api
A design-time factory (RegistryDbContextFactory) supplies a placeholder connection string so the
tooling can build the model without a running database.
Releasing
The registry ships as a container image to GHCR, not a binary. release-please drives stable
:X.Y.Z + :latest images; the edge workflow pushes a rolling :edge on every push to main. See
How the registry works → Releasing for the version/release model.
Troubleshooting
'<' is an invalid start of a valuefrom the CLI — you pointed--registryat something that returned HTML (commonly the Aspire dashboard port) instead of the API. Usehttps://localhost:7443.- First run logs
relation "__EFMigrationsHistory" does not exist— expected on an empty database: EF probes for the migrations table, finds none, then creates the schema. It only happens once. - Postgres logs
could not accept GSSAPI security context— harmless. The Npgsql client tries Kerberos/SSPI first on Windows, then falls back to password auth. - HTTPS / certificate errors — run
dotnet dev-certs https --trust. - GitHub sign-in fails or loops — confirm the OAuth app's callback is exactly
https://localhost:7443/signin-githuband that the client id/secret are set in the AppHost's user-secrets.