byoc
# Bring Your Own Azure Subscription
Backify's BYOC model keeps application resources and billing in the customer's subscription while Backify retains authorization, policy, approval, audit, and deployment control.
## Identity boundaries
| Identity | Permissions | Used by |
|---|---|---|
| Backify deployment principal | Contributor on one designated resource group; ACR/Blob/Key Vault data roles | Backify worker only |
| GitHub CI principal | `AcrPush` on one customer registry | Repository workflow through GitHub OIDC |
| Application runtime identity | `AcrPull`, Blob data contributor, Key Vault secret reader | Customer application containers |
No client secret is generated or stored. The Backify worker exchanges its managed-identity assertion for the customer's deployment principal. GitHub receives repository- and branch-specific federated credentials. AI agents only call Backify APIs and never receive either identity.
## Hosted Backify worker configuration
```text
AzureByoc__WorkerManagedIdentityClientId=<backify-worker-identity-client-id>
AzureByoc__FederationIssuer=<managed-identity-issuer>
AzureByoc__FederationSubject=<managed-identity-subject>
AzureByoc__FederationAudience=api://AzureADTokenExchange
AzureByoc__AllowDeveloperCredential=false
```
The worker identity must be able to obtain an `api://AzureADTokenExchange/.default` assertion. Each customer onboarding script creates a federated credential that trusts this issuer/subject pair.
## Customer onboarding
An Owner or Administrator selects **Connect Azure**, signs in to Microsoft, selects a subscription and region, and confirms. Backify automatically:
1. discovers subscriptions the administrator may manage;
2. creates the designated resource group;
3. creates separate Backify deployment and CI application identities;
4. configures Backify worker federation;
5. creates Container Apps environment, ACR, Storage, Key Vault, and application runtime identity;
6. applies scoped RBAC assignments;
7. validates resources and creates the organization's default deployment target;
8. assigns that target to unassigned applications.
The administrator's delegated OAuth credentials are encrypted, used only by the worker during onboarding, and erased on completion. Restricted tenants can use the advanced manual script or deploy `infrastructure/azure/byoc` through Terraform.
## Source and CI/CD
The application creator selects **Connect GitHub**, installs the Backify GitHub App for selected repositories, and chooses a repository and branch. Backify automatically:
- configures repository- and branch-specific GitHub OIDC federation;
- commits `.github/workflows/backify.yml`;
- configures required GitHub Actions variables;
- records the repository and immutable branch selection.
The workflow builds and pushes an image, obtains the registry digest, and passes only this immutable reference to Backify:
```text
customer.azurecr.io/application@sha256:...
```
Backify rejects tags, mutable references, and images outside the connection's customer registry.
GitHub obtains an Entra token for the Backify API using OIDC. Backify registers the CI service principal as an organization `Publisher`; it cannot manage connections, members, secrets, or policy. Publish requests still pass policy evaluation and approvals.
## Deployment
The worker resolves the application's target and invokes Azure only after Backify authorization has queued an operation. It deploys a Container App revision with:
- customer runtime managed identity;
- customer ACR pull through managed identity;
- immutable image digest;
- HTTPS ingress;
- multiple-revision mode;
- organization/application/environment tags;
- health and deployment history recorded by Backify.
Preview and production are separate Container Apps. Rollback redeploys the previously recorded immutable digest through the same provider and audit path.
## Local development
The local worker has no managed identity. For explicit developer testing, mount a short-lived management token:
```powershell
./scripts/refresh-local-azure-tokens.ps1 `
-TenantId <customer-tenant-id> `
-SubscriptionId <customer-subscription-id>
docker compose up --build
```
The generated JSON bundle contains separate short-lived ARM and Key Vault audience tokens. It is mounted read-only into API and worker, is gitignored, and is never copied to PostgreSQL. This mode is enabled only in local Compose. Production configuration rejects developer credentials.
index
# Backify documentation
## Getting started
Create an organization in the portal, create an application, enable authentication/database/storage, then deploy a preview. Publishing validates permissions and evaluates organization policies; rollback selects the previous healthy production deployment.
## Architecture
```mermaid
flowchart LR
A[AI agent / Developer] --> P[Portal / CLI / MCP]
P --> API[Backify API]
API --> Auth[Authentication + RBAC + Policy]
API --> DB[(Control-plane PostgreSQL)]
API --> O[Operation queue]
O --> W[Provisioning worker]
W --> Providers[Provider interfaces]
Providers --> Azure[Azure / Local providers]
Azure --> Runtime[Untrusted workload boundary]
```
The modular monolith owns business rules and transactions; a separate worker performs builds and provisioning. `IComputeProvider`, `IDatabaseProvider`, `IStorageProvider`, `ISecretsProvider`, `IIdentityProvider`, `IObservabilityProvider`, `IDomainProvider`, and `IBuildProvider` prevent Azure terminology from entering public APIs.
The tenant hierarchy is `Organization → Workspace → Application`. Workspaces group applications and may override organization defaults for region, Azure connection/deployment target, and GitHub App installation. Applications inherit workspace settings dynamically unless an application-specific target is deliberately selected.
## REST API
OpenAPI is generated at `/openapi/v1.json`. Tenant routes require `X-Organization-ID`. Important mutation routes accept `Idempotency-Key` and return `202` with an operation ID. Correlation IDs are accepted/returned as `X-Correlation-ID`.
## SDK
`@backify/sdk` provides `auth`, `db`, `storage`, `config`, `integrations`, and `logging`. Browser code cannot retrieve secrets. Runtime brokers scope every SDK call to the application/environment identity.
## CLI and MCP
The `backify` CLI and MCP server only call the API. Configure `BACKIFY_API_URL`, `BACKIFY_ORGANIZATION_ID`, and an OIDC access token. CLI secret values are read from `BACKIFY_SECRET_VALUE`, not command arguments. MCP tools include app creation, capabilities, preview, publish, status, logs, secrets, integration enablement, and rollback.
## Authentication and authorization
Production uses Microsoft Entra OIDC/JWT. Domain users remain provider-neutral. Roles map to permissions centrally; controllers request permissions, never role names. Every tenant query includes the organization ID, deliberately returning not-found for cross-tenant resources.
## Data, storage, and secrets
Local development uses PostgreSQL and isolated filesystem storage. Azure uses PostgreSQL, Blob Storage, Key Vault, and workload managed identities. API secret responses contain metadata only; values are encrypted, never audited/logged, and injected only into authorized server workloads.
## Deployments and domains
Builds reference immutable source revisions and produce image digests. Preview hosts use `{preview-id}.preview.backify.site`; production uses `{slug}.backify.site`. A deployment records actor, digest, environment, health, and previous revision. Custom domains model ownership, certificate, and binding state.
## Governance and security
Policy results are `ALLOW`, `DENY`, `WARN`, or `REQUIRE_APPROVAL`. Approvals are generic organization/application actions. Audit events carry actor, resource, timestamp, and correlation ID without secrets. Generated applications are untrusted and have no access to Azure management APIs, control-plane storage, or other tenant resources.
## Azure and BYOC
Terraform under `infrastructure/azure` creates the managed control-plane foundations. Regions are variables/domain fields rather than constants. `CloudConnection` and ownership mode distinguish `BACKIFY_MANAGED` from future `CUSTOMER_MANAGED` targets; credentials remain represented by managed identity, never API payloads.
See [Bring Your Own Azure Subscription](byoc.md) for the implemented federated onboarding, scoped identities, customer-side Terraform, GitHub OIDC workflow, immutable image deployment, and local validation process.provider-app-setup
# One-time provider application setup
This setup is performed once by the Backify platform operator. Customer tenant administrators and application creators do not perform it.
## Microsoft connection application
Create a multi-tenant Microsoft Entra web application for `api.backify.dev`.
Configure the redirect URI:
```text
https://api.backify.dev/api/connections/azure/callback
```
For local testing, add:
```text
http://localhost:5080/api/connections/azure/callback
```
Add delegated Microsoft Graph permissions requiring administrator consent:
- `Application.ReadWrite.All`
- `AppRoleAssignment.ReadWrite.All`
The user also consents to Azure Resource Manager `user_impersonation`. Backify requests offline access only for the short-lived onboarding session. The delegated refresh token is Data Protection encrypted, never returned to the portal, and destroyed after the worker completes onboarding.
Configure:
```text
Connections__Azure__ClientId
Connections__Azure__ClientSecret
Connections__Azure__BackifyApiAppId
Connections__Azure__BackifyApiAudience
Connections__Azure__BackifyApiPublisherRoleId
```
The Backify API Entra application must expose a `Publisher` application role for service principals. Its role ID is `BackifyApiPublisherRoleId`. Automatic onboarding assigns this role to the customer CI principal.
## GitHub App
Create one GitHub App owned by the Backify organization.
Configure:
```text
Setup URL: https://api.backify.dev/api/connections/github/callback
Request user authorization during installation: disabled
Webhook: optional for this flow
```
Repository permissions:
- Contents: Read and write
- Actions: Read and write
- Metadata: Read-only
The customer chooses exactly which repositories the installation may access. Backify stores only the installation ID. Installation access tokens are generated on demand and expire automatically.
Configure:
```text
Connections__GitHub__AppId
Connections__GitHub__AppSlug
Connections__GitHub__PrivateKeyPem
```
Store the private key in the deployment secret store, not source control or a plain environment file. In Azure, inject it from the Backify control-plane Key Vault.
## Hosted worker federation
Configure the Backify worker managed identity as described in [BYOC](byoc.md). This permanent identity replaces the customer administrator's delegated onboarding session after resources have been created.
## User experience after setup
Tenant administrator:
```text
Connect Azure → Continue with Microsoft → choose subscription/region → Connect
```
Application creator:
```text
Connect GitHub → install Backify for selected repositories → choose repository/branch → Connect repository
```
Backify creates provider identities, infrastructure, OIDC federation, GitHub Actions variables, and the workflow automatically.
adr/0002-provider-neutral-api
# ADR 0002: Provider-neutral public API
**Accepted.** Public contracts expose compute, database, storage, secrets, identity, observability, domains, and builds. Azure implementations and resource identifiers remain internal. This supports Backify Cloud now and BYOC/additional clouds later without changing the agent or application experience.