An Angular 21 + ASP.NET Core 10 authentication starter with JWT auth and multi-channel 2FA (authenticator app, email, SMS). Generate it into your own repository, run the whole stack locally with no external accounts, and try it live first.
Tip
Try it before you clone it: Live demo · Use this template
The demo is this repository, deployed from its tagged releases by its own GitHub Actions pipeline — not a separate showcase app. Register an account and try email confirmation, password reset, authenticator/TOTP enrollment, email and SMS 2FA, and the admin screens. No real email or SMS is sent: messages land in the public mock inboxes — SendGrid mock (email) and Twilio mock (SMS). Both scale to zero, so the first load after idle can take a few seconds.
Tip
The demo runs on a free-tier stack, and the pipeline that deployed it ships in the template too — see Deploy your own — or read how it's built.
Authentication
- ASP.NET Core Identity with JWT issuance and claims
- Registration, login, email confirmation
- Password reset (emailed link) and password change (current password required) — separate flows
- Configurable self-registration
Two-factor
- Authenticator app (TOTP) with QR code enrollment, email codes, SMS codes
- Recovery codes issued on enrollment
- Optional or required 2FA, and a configurable list of available methods
Admin
- User list, create, edit, deactivate, unlock
- Role-based authorization
Development experience
- Entity Framework Core with MySQL (see Database Provider for other providers)
- Full Docker Compose stack — MySQL, Mailpit (SMTP), and SendGrid/Twilio/Postmark mocks
- No external accounts needed for any provider
Quality
- Playwright end-to-end suite against the real containerized app
- CI on every push and PR, SonarQube Cloud quality gate, CodeQL
Deployment included
- A GitHub Actions → Cloud Run pipeline every generated repo inherits
- Workload Identity Federation (no static credentials), secrets in Secret Manager, a free-tier stack — see Deploy your own
Extracted packages
- Auth and notification logic ship as reusable NuGet packages — see Built on
Good fit: developers starting an Angular + ASP.NET Core app who want working authentication and 2FA from day one instead of assembling it from snippets; teams that want self-hosted auth, a complete local dev environment, and a codebase they can freely customize.
Not a good fit: teams that want an external identity provider (Auth0, Entra ID, Cognito, etc.) to own the login experience.
This is a starter template, not a finished app.
flowchart TD
subgraph tpl["angular-dotnet-auth-template (this repo)"]
client["Angular 21 client"] --> api[".NET 10 API"]
end
api --> jwt["DGates.Identity.Jwt2Fa<br/>JWT + multi-channel 2FA"]
api --> np["DGates.Identity.NotificationProviders<br/>email + SMS senders"]
jwt --> np
np --> mocks["dgates-mock-servers<br/>local provider mocks"]
This template is the reference application. Auth and notification capabilities are extracted into independently reusable NuGet packages, and fixes reach generated repos through an ordinary package update.
| Project | What it is | Reach for it when |
|---|---|---|
| angular-dotnet-auth-template (you are here) | Angular + .NET starter with JWT and 2FA | you want a running, customizable app |
| DGates.Identity.Jwt2Fa (NuGet) | JWT issuance and multi-channel 2FA for ASP.NET Core Identity | you have an existing API and want the auth without the template |
| DGates.Identity.NotificationProviders (NuGet) | Email and SMS senders (SendGrid, SMTP, Postmark, Twilio, SNS) | you need swappable notification providers |
| dgates-mock-servers | Public GHCR images mocking SendGrid, Twilio, and Postmark | you want to develop or test notification flows with no accounts |
More from dgates82: DGates.AwsSecretsManager and dotnet-nuget-release-template, the template the two packages above were scaffolded from.
- Click Use this template on GitHub to generate your own repository from this one — not a fork, a fresh repo with its own history.
- Clone your new repo locally.
- Follow Quickstart below to confirm it works before changing anything.
- Work through Customizing to make it yours.
Docker-first. From a fresh clone:
docker compose up -d mysql sendgridmock smsmock
cd api && dotnet tool restore
cd AngularDotNetAuthTemplate.Api
dotnet ef database update
cd ../..
docker compose up -d --build apiBrowse to http://localhost:8080. Mock inboxes: SendGrid at http://localhost:3040, SMS at http://localhost:3030.
Prerequisites: Docker, and the .NET SDK 10 (for the migration step above — the container doesn't run migrations itself).
Want hot-reload instead, or to run the API and Angular client separately? See Prerequisites and the rest of docs/LOCAL_DEV.md.
The template doesn't just have a demo — it ships the pipeline that deployed it. Every generated repo inherits .github/workflows/deploy-cloudrun.yml, the Dockerfile, and docs/DEPLOYMENT.md, and can run the same stack on Cloud Run: GitHub Actions → Cloud Run, Workload Identity Federation (no static credentials), app secrets in Secret Manager, Aiven free-tier MySQL with automated power-on handling, and the SendGrid/Twilio mocks deployed as their own scale-to-zero services so no paid email/SMS account is needed.
Important
It's inert until you configure it: a generated repo starts with none of the required Actions variables set, so the deploy job just skips on a tag push. Even if the variables were pointed at this project's values, GCP's own Workload Identity Federation trust — scoped to this exact repository — would reject the token.
Setup checklist (see docs/DEPLOYMENT.md for exact commands):
- Enable the needed GCP APIs and create an Artifact Registry repository in your own project
- Create a Workload Identity pool/provider with the attribute condition scoped to your repository
- Create a deploy service account and grant it access
- Put the app secrets in Secret Manager
- Set up MySQL (Aiven free tier or your own) and add its credentials
- Set the Actions variables and secrets (see docs/DEPLOYMENT.md steps 4-5); the deploy job skips until
GCP_PROJECT_IDis set, but a deploy needs the rest too - Push a
vX.Y.Ztag to trigger a deploy
Free-tier ceiling: see docs/DEPLOYMENT.md.
Every spot that needs a look before you ship is marked TODO(template) (in code comments) or a literal [Application Name] placeholder. Find them all with:
git grep -n "TODO(template)"
git grep -n "\[Application Name\]" -- api client/srcSee docs/CUSTOMIZING.md for the full list, and docs/CONFIGURATION.md for JWT, notification provider, database provider, and Angular feature-flag configuration.
Important
The one thing you must change before deploying: Jwt2FaConfig.SecurityKey in appsettings.json ships with an obviously-fake default. See JWT Configuration in docs/CONFIGURATION.md for the full shape.
MySQL is the only provider this template ships with and tests against. See Database Provider in docs/CONFIGURATION.md for swapping providers.
- Testing: the Playwright end-to-end suite runs against the real containerized app — see Running the End-to-End Suite in
docs/LOCAL_DEV.md. - Upgrading: pre-1.1.0 JWT config migration and Angular's lockstep-versioned dependencies — see docs/UPGRADING.md.
- Troubleshooting: see Troubleshooting in
docs/LOCAL_DEV.md.
This project is licensed under the MIT License.
