BYOSA setup¶
This guide walks you through configuring AppGantry to store your build artifacts in your own Azure Blob Storage account instead of ours. The platform owns the metadata and audit trail; you own the bytes.
For an overview, see the BYOSA concepts page. BYOSA is most useful when you hit one of: heavy distribution (typically $100+/mo in download metering), a compliance requirement, or a data-residency constraint.
Prerequisites¶
You need:
- An Azure tenant where you (or a tenant admin you can reach) can admin-consent applications.
- An Azure subscription with billing enabled.
- The Admin role on your AppGantry organization. If you signed up and created the org, you already have it.
- Your AppGantry login (BYOSA management is gated on a short-lived JWT, not a PAT).
You don't need:
- To share a storage account key with us.
- To share a SAS token with us.
- To configure a service principal client secret or certificate.
- To rotate anything on a schedule.
Our auth model is secret-less: see Step 1 for how that works.
Overview¶
The flow has two phases:
- Azure side (self-service): admin-consent our app, create a storage account + container, grant our app the right role.
- AppGantry side (operator-mediated): send us your three identifiers; an operator validates and flips your org to BYOSA.
The flip is operator-mediated by design.
Phase 1: Azure side¶
Step 1: admin-consent our app¶
This creates an enterprise-app service principal in your tenant. It carries no credentials. It exists so you can assign it a role on your storage container.
Have a tenant admin visit (replace {your_tenant_id} with your Azure AD
tenant ID):
https://login.microsoftonline.com/{your_tenant_id}/adminconsent?client_id=63c04479-2f32-4a1d-909c-b546d98bc4c8
About that client ID
63c04479-2f32-4a1d-909c-b546d98bc4c8 is the application (client)
ID of our multi-tenant app, AppGantry BYOSA Access. It is a
public identifier, not a secret. Confirm it matches our published
trust anchors page before consenting.
The admin reviews the permission request and clicks Accept. After this, an enterprise app named AppGantry BYOSA Access appears under Azure Portal → Enterprise applications. Note the object ID of this enterprise app; you'll grant a role to it in Step 3.
Tip
If your tenant has a Conditional Access policy that blocks consent, work with your AAD admins to allow it for this single client ID. Admin consent is a one-time event; the policy doesn't need to permit interactive sign-in for this app.
Step 2: create a storage account and container¶
Standard Azure procedure. Choose:
- Region: close to where your developers and testers live.
- Redundancy:
LRSis fine for most cases; pickGRSif you need cross-region durability. - Performance tier:
Standard(Hot access tier).
Then create a container inside the account:
- Name: must satisfy Azure rules: 3-63 chars, lowercase alphanumeric
and hyphens, must start with a letter or digit, no consecutive hyphens,
not a reserved name (
$logsetc.). We recommendappgantry-buildsso support recognises it at a glance, but you choose. - Public access level:
Private (no anonymous access). AppGantry mints time-limited signed URLs for every download. - Reserve the container for AppGantry. We write files under our own
path scheme (
{project_id}/{build_id}.bin) and assume nothing else writes to it.
Step 3: grant our app the right role¶
In the storage account's IAM blade:
- Navigate to your container (not the account root, ideally).
- Access Control (IAM) → Add → Add role assignment.
- Role: Storage Blob Data Contributor.
- Assign to: User, group, or service principal.
- Search for AppGantry BYOSA Access (the enterprise app from Step 1). Select it.
- Save.
Container scope, not account scope
Account scope works (and we'll validate against it), but it grants our app data-plane access to every container in the account. Container scope keeps the blast radius tight.
Reader is not enough
Storage Blob Data Reader lets us retrieve blobs but not upload them; setup validation will fail at the marker-write step with a clear error message.
AAD role propagation takes about 5 minutes. If you retry setup immediately after granting the role you may see a token-exchange or 403 error. Wait and retry.
Phase 2: AppGantry side¶
Step 4: gather your three identifiers¶
You'll send these to support:
| Where to find it | |
|---|---|
| Tenant ID | Azure Portal → Microsoft Entra ID → Overview → Tenant ID |
| Account URL | e.g. https://acmebuilds.blob.core.windows.net |
| Container name | The container you created in Step 2 |
Step 5: request the flip¶
Send your three identifiers to support (or your AppGantry operator contact). An operator runs setup, which executes a five-stage validation pipeline against your Azure setup before committing anything in our database:
- Token exchange: verifies admin consent landed and the federated trust is reachable.
- Container existence: verifies the container exists. We will not auto-create containers in your tenant.
- Marker write: uploads a small marker blob to verify write permission.
- Marker delete: removes the marker to verify delete permission.
- Residue check: confirms the marker is actually gone (catches soft-delete retention swallowing the purge).
If anything fails, setup returns a structured remediation report:
{
"success": false,
"failure_stage": "put_marker",
"responsibility": "customer",
"summary": "Couldn't write a marker blob to 'appgantry-builds'. The most common cause is that the role grant is Storage Blob Data Reader instead of Storage Blob Data Contributor...",
"remediation": [
"Confirm the role assignment is Storage Blob Data Contributor...",
"Verify the role binding is scoped to the container...",
"Wait ~5 minutes for AAD propagation..."
],
"docs_url": "https://docs.appgantry.com/guides/byosa-setup/",
"failure_detail": "<raw Azure SDK error text for reference>"
}
responsibility: "customer": something on your Azure side needs fixing. Theremediationlist is concrete steps.responsibility: "platform": something on our side failed. Contact support; includefailure_detailandfailure_stage.
Failed setup attempts do not write to our database and do not pollute your audit log; there's no cost to iterating.
A successful setup flips your org to byosa. From this point, every
build upload lands in your container, and every download streams
through a time-limited SAS URL we mint against your storage account.
After setup¶
Verify¶
Confirm the current config any time:
Run a diagnostic to re-validate end-to-end (e.g. after an Azure outage):
The diagnostic returns the same structured report shape as setup, with
success: true when everything works.
Rotating to a different container or account¶
Send support the new identifiers. If you change the container_name or
account_url and your organization already has builds, those builds'
download URLs will 404 after the rotation, because their storage paths point
at the previous container. The operator will confirm you accept this
before running it. If you want to keep existing build downloads working
through the rotation, the blob data has to be copied between accounts;
support coordinates that manual flow.
Tenant ID rotation alone (same account, same container) does not move any bytes.
Teardown¶
To move back to hosted storage, contact support. Teardown is blocked by default if your organization has live builds, because their download URLs would 404 after the flip back to hosted, so you'll either delete the affected builds first or explicitly accept the breakage.
After teardown you'll get a customer-side cleanup checklist for the dangling enterprise-app SP in your tenant:
- Azure portal → Enterprise applications → search for AppGantry BYOSA Access.
- Properties → Delete.
- Optionally remove the role assignment on your container.
We cannot remove the enterprise app from your tenant for you; we don't have Microsoft Graph permissions in your tenant.
See also¶
- BYOSA concepts: what BYOSA gives you and its trade-offs.
- Plans & pricing: when BYOSA pays off.