| name | azure-spa-clean-architecture-bootstrap |
| description | Own Azure platform, identity, secretless config, IaC, and GitHub release and deployment automation for React Router + Prisma v7 web apps that already follow enforce-react-spa-architecture. Use when the work is primarily Azure runtime-mode selection, Microsoft Entra ID integration or Azure CLI app registration when end-user authentication is required, Azure Container Apps, local SQLite development with Azure SQL Database for hosted persistence, Azure App Configuration, Key Vault, Managed Identity, local DefaultAzureCredential setup, GitHub Actions OIDC, GHCR image release, or production deployment verification. Do not use this skill for spec, planning, or branch-and-PR workflow or for base app-code architecture rules. |
Azure Spa Clean Architecture Bootstrap
Overview
Use this skill to layer Azure hosting, identity, and GitHub delivery decisions onto the base React Router clean architecture owned by enforce-react-spa-architecture. Preserve SPA-style navigation, but switch to a server runtime whenever OAuth callbacks, Prisma, server-only secrets, or Azure SQL access make a static-only SPA the wrong abstraction.
This skill owns Azure platform, Microsoft Entra ID, secretless config, IaC, and release workflow guidance. Keep code structure, UI guardrails, and general verification rules in the companion skill, and repeat them here only when they are critical to protect Azure-specific boundaries.
This skill does not own /doc/spec, /doc/plan.md, commit-log workflow, branch naming workflow, or PR management; use a repository workflow skill for those concerns and keep this skill focused on platform deltas.
Treat requests for "Microsoft auth" as Microsoft Entra ID only when the app actually needs user authentication. If the app does not need auth, skip the app registration and auth guidance.
Prefer a secretless configuration model: do not introduce .env or .env.example for Azure-hosted apps. Put non-secret runtime configuration in Azure App Configuration, put secrets in Key Vault, use local DefaultAzureCredential during development, and use ManagedIdentityCredential for deployed app-to-Azure and Azure SQL authentication.
Keeping the same database engine across environments is usually safer. When this skill adopts SQLite for developer speed, treat it as local-development-only storage and require Azure SQL Database for every Azure-hosted environment that persists relational data.
Surface Azure prerequisites early. If the project will definitely require specific RBAC assignments, tenant or subscription access, SQL admin setup, App Configuration or Key Vault access, or an unavoidable Service Principal for deploy or migration paths, request those at the beginning of development instead of discovering them mid-implementation.
When the app requires user authentication, prefer a real local sign-in path with a dev or test Microsoft Entra ID registration and test identities rather than a hidden development auth bypass.
Companion Skill Requirement
- Install
enforce-react-spa-architecture together with this skill. Do not use this skill as a standalone replacement for the base architecture skill.
- If the companion skill is missing, install it before continuing from https://github.com/anaregdesign/skills/tree/main/skills/development/enforce-react-spa-architecture.
- Prefer
$skill-installer for the install step when another Codex instance needs to fetch the published skill from GitHub.
- Continue only after the sibling references under
../enforce-react-spa-architecture/references/ are locally available.
Quick Start
- Choose the runtime mode first:
- Keep pure SPA mode only when the app has no server-only secrets, no social login callback, no Prisma-backed mutations, and no protected server endpoints.
- Use React Router framework runtime when the app needs auth callbacks, cookies, Prisma, Azure SQL, or server-owned secrets.
- If the app persists relational data, use SQLite for local development and Azure SQL Database for every Azure-hosted environment.
- Surface prerequisites before deep implementation:
- list the Azure tenant, subscription, resource group scope, and RBAC assignments that are definitely required
- identify any required SQL admin or migration identity setup
- identify whether GitHub Actions OIDC setup or another unavoidable Service Principal is required
- request these prerequisites at project start instead of waiting for release hardening
- Confirm the companion skill is installed:
- required skill:
enforce-react-spa-architecture
- published URL:
https://github.com/anaregdesign/skills/tree/main/skills/development/enforce-react-spa-architecture
- if missing, install it with
$skill-installer before reading the sibling references
- Read the base architecture references from the sibling skill:
- Read the Azure and GitHub references in this skill:
- Classify the change:
- route or UI composition
- Microsoft Entra ID auth or app registration when authentication is required
- auth or session boundary
- persistence or migration
- Azure infrastructure
- GitHub workflow or release automation
- production verification
Repository Additions
- Put Azure IaC in
infra/.
- Put deployment and bootstrap helpers in
scripts/azure/.
- Put CI and release automation in
.github/workflows/.
- Keep Azure project wiring in
azure.yaml.
- Keep container packaging in
Dockerfile.
- Keep secretless config bootstrap and parsing in
app/lib/server/infrastructure/config/ or the narrowest equivalent server config module.
- Keep configuration contract documentation in
README.md.
- Add a cheap health probe in
app/routes/health.ts.
Template Assets
- Use the generic repo templates in
assets/templates/.
- Replace placeholder tokens such as
__APP_NAME__, __SERVICE_NAME__, and __PUBLIC_APP_URL__ only after the target app's naming rules are clear.
- Keep the template vocabulary generic. Do not leak app-specific names, resource-group names, or domain nouns back into the shared asset files.
- Start from these templates when bootstrapping:
assets/templates/azure.yaml
assets/templates/Dockerfile
assets/templates/app/routes/health.ts
assets/templates/.github/workflows/release-container-image.yml
assets/templates/scripts/azure/postprovision.sh
assets/templates/infra/main.bicep
Non-Negotiable Rules
- Install and keep
enforce-react-spa-architecture available together with this skill.
- Keep all dependency, placement, UI, and verification rules from
enforce-react-spa-architecture.
- Do not redefine the companion skill's general coding guardrails here. Use this skill for Azure, identity, infrastructure, and delivery deltas, and repeat code-level rules only when they protect those deltas.
- Keep Prisma and Azure SDK imports inside server infrastructure or deployment code.
- Treat "SPA" as a UX target, not as a requirement to remove the server runtime.
- Prefer React Router framework runtime over bolting ad hoc APIs onto a static bundle when auth, persistence, or secret-backed integrations need a server.
- Prefer Azure Container Apps for apps that need a server runtime. Use Static Web Apps only for truly static frontends.
- Use SQLite only for local development.
- When the app is hosted on Azure and persists relational data, use Azure SQL Database rather than SQLite.
- Prefer Azure SQL Database serverless for Azure-hosted relational persistence unless workload characteristics force another SKU.
- Front-load known Azure prerequisites. Ask for required tenant access, subscription access, RBAC assignments, SQL admin setup, and any unavoidable Service Principal before substantial implementation begins.
- When authentication is required, prefer
Microsoft Entra ID over portal-only or ad hoc "Microsoft auth" descriptions, and keep the chosen signInAudience explicit.
- Do not use
.env or .env.example for Azure runtime configuration. Use Azure App Configuration for non-secret settings and Key Vault for secrets.
- Use local
DefaultAzureCredential during development after az login or azd auth login.
- Use
ManagedIdentityCredential for deployed app-to-Azure and Azure SQL authentication. Do not rely on a broad DefaultAzureCredential chain in production.
- Use
DefaultAzureCredential or Managed Identity only where runtime SDK support is real. Do not assume Prisma CLI or schema migration flows inherit that auth automatically.
- Treat SQLite-to-Azure-SQL provider differences as real delivery risk. Validate migrations, query behavior, and generated SQL against Azure SQL Database before release.
- Separate runtime identity from migration or admin identity.
- When the app requires user authentication, prefer a separate dev or test app registration from the production registration, and use a separate test tenant when production-tenant policies or risk make safe testing hard.
- Keep localhost redirect URIs in the dev or test registration, or document clearly why they still exist in another registration. Remove unnecessary development redirect URIs from the production registration.
- Use test users, test groups, or invited guest users to complete local sign-in flows. If testing inside the production tenant, restrict the test enterprise application to specific users or groups.
- Do not treat a hidden local auth bypass as the standard development path for an app that requires authentication.
- Prefer scripted
az or az rest app registration changes over portal-only click paths so redirect URIs, audience, and secret mode stay reproducible.
- Use GitHub Actions OIDC to Azure. Do not store Azure client secrets in GitHub.
- Prefer Managed Identity and OIDC over Service Principals, but if a Service Principal is definitely required for deploy, migration, or external automation, identify and request it during bootstrap rather than during release stabilization.
- Keep repository governance explicit: protected default branch, required checks, and production Environment scoping.
- Deploy immutable release-tag images, not mutable
latest.
- Keep production values in GitHub Environments and Azure-managed secret stores rather than in repo files.
- Add explicit health endpoints and post-deploy smoke tests.
- Keep README, callback URLs, configuration contract docs, release notes, and IaC in sync with the deployed system.
Implementation Workflow
0. Choose the correct runtime contract
- Keep pure SPA mode only for fully static frontends.
- Enable server runtime before writing features that need OAuth callbacks, cookies, Prisma, secrets, or server-owned data access.
- Keep route modules responsible for HTTP wiring, loader or action composition, and top-level dependency assembly only.
1. Bootstrap the app and architecture
- Confirm
enforce-react-spa-architecture is installed from the published GitHub path before relying on sibling references.
- Follow the sibling architecture references before adding cloud features.
- Keep this skill focused on platform deltas after the companion skill has established code structure, UI rules, and verification gates.
- Surface the Azure prerequisites now: required RBAC, tenant or subscription access, SQL admin setup, App Configuration or Key Vault access, and any unavoidable Service Principal or federated deploy identity.
- Ask for these prerequisites before the team gets deep into implementation so platform access does not become a late blocker.
2. Add cloud-facing repository structure intentionally
- Put Azure IaC in
infra/.
- Put deployment and provisioning scripts in
scripts/azure/.
- Put GitHub release and deploy workflows in
.github/workflows/.
- Keep secretless bootstrap config and runtime parsing explicit and centralized in server infrastructure.
- Keep one clear bootstrap path for Azure App Configuration and Key Vault instead of scattering fallback
.env reads.
- Keep app-specific scripts idempotent and safe to re-run.
3. Add auth and session boundaries at the edge when authentication is required
- Handle social login callbacks, cookies, and session state at the route or server edge.
- Only enter this step when the app actually needs authentication.
- When the app needs Microsoft auth, decide early whether the runtime contract is
web or spa.
- Prefer
web platform redirect URIs and server-owned cookie sessions when React Router framework runtime already exists for Prisma, secrets, or protected server endpoints.
- Use
spa platform redirect URIs and browser PKCE only when the frontend is truly static and has no server-owned secret boundary.
- Create or update the
Microsoft Entra ID app registration from Azure CLI or az rest, and keep redirect URIs plus audience in versioned notes.
- For local development, prefer a dev or test app registration with localhost callback URLs, test identities, and tenant policy settings that let the team complete sign-in safely without weakening production registration hygiene.
- If developers need the same sign-in behavior as production, replicate the relevant Conditional Access, consent, and token-lifetime policies in the dev or test environment instead of bypassing auth in application code.
- When a
web registration needs a confidential client secret or certificate, keep it in Key Vault and resolve it through the same secretless config path used in production rather than copying it into .env.
- Keep authorization decisions in use cases or domain policies.
- Keep provider profile DTOs out of
domain until a stable internal model is necessary.
- Document environment-specific callback URLs in README and app registration notes.
4. Add persistence and identity intentionally
- Keep repository ports in the companion skill's domain layer, and place Azure SQL or SQL Server adapters in
app/lib/server/infrastructure/repositories/.
- Use SQLite for local development only, and keep Azure-hosted environments on Azure SQL Database. Do not plan to run a SQLite file inside Azure-hosted runtime environments.
- Use local
DefaultAzureCredential in development, and use ManagedIdentityCredential for deployed app-to-Azure and Azure SQL authentication when the driver path supports it.
- Keep migrations explicit and separate from app startup.
- Treat the SQLite local-development path and Azure SQL Database hosted path as different providers that need explicit validation.
- Keep
db_datareader and db_datawriter on runtime identities. Reserve elevated roles for migration or admin identities.
5. Prepare Azure deployment
- Add a container-friendly
Dockerfile.
- Add
azure.yaml and declarative infrastructure.
- Prefer Container Apps, Managed Identity, Azure App Configuration, Key Vault, Application Insights, and, when relational persistence is required, Azure SQL Database serverless as the default platform set.
- Add
/health and keep probes cheap.
- Keep resource naming, region choice, and scope boundaries deliberate.
6. Prepare GitHub delivery
- Build and publish the container image on
release.published.
- Deploy only after image publish succeeds.
- Use GitHub Environment protection for production.
- Keep OIDC federation subject scoped to the repository and environment.
- Use GHCR by default unless the platform requires ACR.
7. Verify before push and before release
- Run tests, typecheck, lint, and build.
- Review boundary drift and forbidden imports.
- Validate workflow syntax and IaC before release.
- When the app requires user authentication, verify the documented local sign-in path with the intended dev or test users before release.
- If local development uses SQLite, verify the deployed environment has switched to Azure SQL Database before release.
- Smoke-test the deployed revision and confirm callback URLs, health checks, Azure SQL Database connectivity, and migration state.
8. Operate and hand off cleanly
- Update README with architecture, Azure topology, required config keys and identities, callback URLs, and release flow.
- Record what is verified versus what still needs cloud-side confirmation.
- Avoid leaving partial infrastructure, stale releases, or unmanaged identities without noting the follow-up work.
Placement Guide
- Need core React Router clean-architecture rules: use the sibling
../enforce-react-spa-architecture/ references.
- Need Azure IaC:
infra/
- Need Azure deployment scripts:
scripts/azure/
- Need GitHub release and deploy workflows:
.github/workflows/
- Need health probes:
app/routes/health.ts
- Need
Microsoft Entra ID auth contract, callback, or local sign-in guidance when authentication is required: references/entra-user-auth-and-runtime-contracts.md
- Need reproducible Azure CLI or
az rest app registration setup: references/entra-app-registration-cli.md
- Need secretless server config bootstrap, App Configuration, Key Vault, or local
DefaultAzureCredential guidance: references/azure-workload-identity-and-secretless-config.md
- Need Azure SQL identity and permission guidance:
references/azure-sql-identity-and-permissions.md
- Need server config bootstrap and parsing implementation placement:
app/lib/server/infrastructure/config/ or the narrowest equivalent under app/lib/server/infrastructure/
- Need Azure SQL or SDK adapters implementation placement:
app/lib/server/infrastructure/repositories/ and app/lib/server/infrastructure/gateways/
- Need runtime config contract documentation:
README.md
References