S
supero.docs
Documentation/Deployment/Deploy to Your Own AWS or GCP

Deploy to Your Own AWS or GCP

Run your app's UI in your own AWS or GCP account, on your own cloud bill, while your data and business logic stay on Supero's backend. The Connect and Deploy flow for both clouds, exactly what each grant allows, how to verify a deploy, and how to tear it down.

Deploying into your own AWS account: a one-time CloudFormation trust stack, then per-deploy calls to S3, CodeBuild, ECR and ECS Express
Supero calls your cloud's APIs with credentials you issue. It holds no AWS identity of its own.

What This Does

Only your app's UI container runs in your cloud account — everything the app calls stays on Supero's backend. The container proxies /api and /ai calls back to api.supero.dev with a scoped, read-only key, so no customer data ever lands in your AWS or GCP account. Builds run in your account (CodeBuild on AWS, Cloud Build on GCP) and are billed to you.
text
Your users' browser --HTTPS--> UI container (your AWS or GCP account) --/api, /ai--> api.supero.dev
                                     |  serves the app UI                    (auth, data, services, AI)
                                     +- built by CodeBuild / Cloud Build, entirely in your own account
  • •No admin credential ships in the container. The deployed bundle carries only non-secret identifiers (which Supero project and tenant it points at) plus a scoped read key for the API proxy, minted fresh on every deploy.
  • •End users authenticate as themselves. The container forwards each visitor's own JWT to Supero; there is no shared service credential standing in for your users.
  • •One bundle, three clouds. The same app bundle is what your CodeBuild or Cloud Build job builds — there is no separate per-cloud source tree to maintain. The image itself is not identical to the one Supero Cloud runs: Supero Cloud builds from a platform-managed container template, while your cloud builds the Dockerfile that ships inside the bundle.
  • •Your cloud credentials are never handled by the app-generation service. They are stored encrypted against the project and read only inside the integration handler that talks to your cloud.

How Supero Reaches Your Cloud

The two clouds use materially different credential models. If a security reviewer is going to ask you one question about this feature, it will be this one, so it is worth stating precisely.

AWS — a long-lived access key you issue

The CloudFormation stack you run creates a scoped IAM user in your account and an access key for it. You paste that key into Supero, which stores it encrypted and authenticates as that user on every deploy. There is no cross-account role assumption and no external ID: Supero holds no AWS identity of its own, so there is nothing for your account to trust.

⚠️ This is a weaker posture than short-lived credentials, and Supero says so

Supero's own AWS onboarding notes describe this model plainly: it "stores a long-lived customer AWS access key (encrypted) in Supero", which is "a weaker posture than short-lived, role-assumed credentials." The mitigations are that the key is scoped by three customer-managed IAM policies to the specific bucket, build project, registry and roles the stack created, and that you can revoke it unilaterally at any time by deleting the access key or the stack. Rotate it on whatever schedule your policy requires — the connect step is idempotent and re-pasting a new key is the only step needed.

GCP — short-lived impersonation, no key

On GCP no key is ever created, downloaded, or stored. You grant Supero's deployer service account the token-creator role on a deploy service account in your project, and Supero mints a one-hour token for it on each deploy. This is plain GCP-to-GCP service-account impersonation — it is not Workload Identity Federation, and there is no cross-cloud trust configuration to maintain. Removing that one IAM binding cuts off access immediately.

ℹ️ Neither path generates infrastructure-as-code at deploy time

Supero calls your cloud provider's APIs directly with your credentials. It does not write Terraform, CloudFormation, or manifests into your account on each deploy. Infrastructure-as-code appears exactly once, as onboarding you apply yourself: a CloudFormation template on AWS, a setup script on GCP. After that, every deploy is API calls against the resources that onboarding created.

The URL You Get

The public address of a deployed app is generated by your cloud provider. You do not choose it, and on AWS it does not stay the same.
CloudURL shapeStable across redeploys?
AWS (ECS Express)An AWS-generated host under *.ecs.{region}.on.awsNo — it changes on every deploy
GCP (Cloud Run)A Google-generated host under *.run.appYes, as long as the service is not deleted

⚠️ On AWS, your app's URL changes every time you deploy

The ECS service name is salted with per-deploy random entropy. This is deliberate: ECS Express holds a torn-down service name in an INACTIVE state for roughly an hour, and a deterministic name would collide with its own predecessor on any redeploy inside that window. The cost of avoiding that is a new hostname on every deploy. Do not hand an AWS deploy URL to end users as a stable address, do not bookmark it, and do not put it in a QR code or an email campaign. If you need a stable public address today, Supero Cloud or GCP are the options.

🚨 Custom domains are not implemented

You cannot point your own domain at an app deployed to your AWS or GCP account. The platform makes no Route 53, ACM, Cloud DNS, or Cloud Run domain-mapping calls, and there is no custom-domain field in the deploy configuration for either cloud. The custom-domain fields you may see in workspace and tenant settings are tenant-routing text fields — their own help text tells you to configure DNS manually — and they do not affect a deployed app. Nothing stops you putting your own CloudFront distribution or load balancer in front of the service yourself, but that is your infrastructure and Supero neither creates nor tracks it. For a supported arrangement, mail [email protected].

Prerequisites

  • •A plan with a live-deployment allowance. Live deployments start at Starter — see Plans & Billing. A deploy with no allowance left returns a 402 upgrade prompt. If the entitlement check cannot be completed, the deploy returns 503 and is safe to retry — this path deliberately fails closed, because a deploy spends money in your account.
  • •A Supero login with permission to update the project (project_admin or domain_admin).
  • •An app that has already been generated in the project — at least one completed build. The deploy flow needs a bundle to ship.
  • •An AWS or GCP account you administer, with billing enabled — this is the account the UI container runs in and is billed to.
  • •The supero CLI for the one-command connect: pip install --upgrade supero. The browser wizard can walk you through the equivalent console steps on AWS without it.

ℹ️ This is separate from self-hosting Supero

Deploying to your own AWS or GCP only moves the app's UI. Your data, authentication, and AI generation always stay on Supero's backend. If you need the platform itself running on infrastructure you control, see On-Premise Deployment — and note that deploy-to-your-own-cloud is itself a cloud-only capability that does not ship in the on-premise package.

How It Works

Every deploy to your own cloud goes through the same four stages, on both AWS and GCP:
StepWhat happens
1. Supero prepares the bundleYour app's identity, namespace, and API configuration are baked into a source archive that is scanned for secrets before it leaves Supero. No credential is included.
2. Your cloud builds itCodeBuild (AWS) or Cloud Build (GCP) builds the image inside your account and pushes it to your own registry — ECR or Artifact Registry.
3. Your cloud runs itECS Express Mode (AWS) or Cloud Run (GCP) serves the UI on a public URL in your account.
4. Data stays in SuperoThe running container proxies /api and /ai to Supero with a scoped read key. No customer data lands in your cloud.
The deploy is driven by your browser: a start call kicks off the build and hands back a non-secret handle, and the panel polls a status endpoint with that handle until the phase reaches running. Phases are building, then deploying, then running — or failed. The start call is bounded to about 85 seconds so it returns cleanly rather than hanging behind an edge timeout; the build continues in your account regardless.

⚠️ There is no server-side deploy record

The deploy handle lives in your browser. Nothing durable is written on the Supero side while an AWS or GCP deploy is in flight. If you close the tab mid-deploy, the build and the service still complete in your own account — but the panel loses track of them, and reopening it will not show the deploy in progress. Recover by looking directly at CodeBuild or Cloud Build, and at the ECS or Cloud Run console. This differs from Supero Cloud, which does keep a durable status record you can poll from anywhere.

Deploy to AWS

AWS deploys run on ECS Express Mode, which provisions a Fargate service, a load balancer, a managed HTTPS certificate, and a public URL from just an image and two IAM roles. The one-time Connect step launches a CloudFormation stack that creates a scoped deploy identity plus that shared build and run infrastructure.

Connect, in one command

Run this in AWS CloudShell, signed in to the target account as an admin. The template is bundled inside the SDK and deployed inline, so there is no S3 bucket to pre-create, and the command prints the stack outputs when it finishes.
bash
pip install --upgrade supero
supero connect-aws --region us-east-1

# optional:
#   --stack-name supero-connect     name of the CloudFormation stack
#   --resource-prefix supero        prefix for the resources it creates
Prefer the console? Launch the same CloudFormation template from the wizard's Setup guide tab, tick the acknowledgement for named IAM resources (CAPABILITY_NAMED_IAM), and create the stack. It takes roughly two to three minutes to reach CREATE_COMPLETE. Either way, the stack takes a single parameter — a resource prefix — and is safe to re-run.

What the stack creates

  • •An S3 deploy bucket for source archives, encrypted with AES-256 and set to expire objects after 7 days.
  • •An ECR repository for the built images.
  • •A CodeBuild project and its service role, with privileged mode enabled so it can build container images.
  • •An ECS task execution role and an ECS infrastructure role — the latter is what lets ECS Express provision the load balancer for you.
  • •Two App Runner roles, for the legacy runtime. New connections do not use them.
  • •A scoped IAM user and one access key for it, with three customer-managed policies attached (three rather than one because an IAM user's inline policy budget is too small to hold them).

Paste seven values back

The stack emits ten outputs. Seven of them are required by the Connect form — all seven, not a subset. The remaining three are the two legacy App Runner role ARNs, which new connections ignore, and Region, which you use to confirm the region selector matches the region you launched the stack in.
Stack outputWhat it is for
AwsAccessKeyIdThe scoped deploy identity Supero authenticates as
AwsSecretAccessKeyIts secret — stored encrypted
DeployBucketWhere the prepared source archive is uploaded
EcrRepoUriThe registry CodeBuild pushes the image to
CodeBuildProjectNameThe build project Supero starts
EcsTaskExecutionRoleArnECS Express task execution role
EcsInfrastructureRoleArnECS Express infrastructure role — provisions the load balancer
Region (not pasted)Confirm the wizard's region selector matches this
Click Connect. Supero validates the key with a read-only identity check and stores it encrypted against the project.

Deploy

Click Deploy. The panel polls until the phase reaches running and then shows the URL. Every redeploy after that reuses the connection and is a single click — but produces a new hostname, as described above.

What the deploy user can do

Permission groupScope
IdentityRead its own caller identity. Nothing else.
BuildUpload source to the named S3 deploy bucket; start and read the named CodeBuild project; read and push to the one named ECR repository.
Run (ECS Express)Create the Express service; update, delete, and describe scoped to services named supero-*; pass role only to the two ECS roles this stack created.
The deploy user never touches EKS, RDS, Route 53, ACM, or CloudFormation at runtime, and it cannot assume any role. The load balancer that fronts your app is provisioned by ECS Express itself through the infrastructure role, not by a direct call.

💡 ECS Express is the runtime for new connections

Accounts already deployed on App Runner keep working on it, and the stack still creates the App Runner roles for that reason. Every new connect provisions the ECS Express roles and deploys to ECS Express.

Deploy to GCP

GCP deploys run on Cloud Run, built by Cloud Build, from source staged in a bucket in your project. Because Supero itself runs on GCP, the trust model is plain GCP-to-GCP impersonation: Supero mints a short-lived token for a deploy service account you grant, and no service-account key is ever created, downloaded, or stored.
Deploying into your own GCP project: a one-time setup script grants impersonation, then each deploy stages source to GCS, builds with Cloud Build, and runs on Cloud Run
The same shape as the AWS path: onboarding you apply once, then API calls per deploy.

Connect, in one command

Copy the External ID the wizard shows, then run this in Google Cloud Shell inside the target project. It is idempotent and safe to re-run — which is also how you pick up changes to the grants after a platform update.
bash
pip install --upgrade supero
supero connect-gcp \
  --project-id <your-gcp-project> \
  --external-id <copied from the wizard> \
  --region us-central1
The CLI runs the same setup script the wizard offers for download, passing your project, region, external ID, and Supero's deployer service account through the environment. Running the script directly is equivalent:
bash
# In Cloud Shell, inside YOUR GCP project — values as shown by the wizard
PROJECT_ID=<your-gcp-project> \
SUPERO_DEPLOYER_SA=<value shown in the wizard> \
EXTERNAL_ID=<copied from the wizard> \
REGION=us-central1 \
bash gcp-setup.sh

⚠️ The setup script is the only supported path

There is no supported Terraform equivalent. Any Terraform you may have seen for this has diverged from the shipped script — it still applies an IAM condition on the Cloud Run grant that was removed as verified-broken, and it omits two bindings the build needs — so a project provisioned that way fails partway through a deploy. Use supero connect-gcp or the setup script it runs.

What the setup creates

  • •Six APIs enabled: Cloud Run, Cloud Build, Artifact Registry, IAM, Cloud Storage, and IAM Service Account Credentials.
  • •An Artifact Registry repository for the built images.
  • •A GCS bucket for staged source, with a 7-day delete lifecycle rule.
  • •A Cloud Run runtime service account, deliberately created with no project roles at all — the app only proxies to api.supero.dev over HTTPS, so it needs nothing.
  • •A deploy service account, which is the identity Supero impersonates.

Paste six values back

The script prints six values. All six are required — region included. Paste them into the Connect form and click Connect; Supero verifies it can impersonate your deploy service account.
setup outputPaste into
gcp_project_idProject ID
regionRegion — required, not optional
deploy_sa_emailDeploy service account
artifact_registry_repoArtifact Registry repo
cloud_run_service_accountCloud Run runtime service account
source_bucketSource bucket

What the setup grants

GrantOnWhat it is for
artifactregistry.writerThe app's Artifact Registry repoPush the built image
run.adminThe whole project, with no conditionCreate, update, and delete the Cloud Run service — see the warning below
cloudbuild.builds.editorThe projectRun the build
storage.objectAdminThe source bucket onlyUpload prepared source
iam.serviceAccountUserThe Cloud Run runtime SAAttach the runtime SA to the Cloud Run service
iam.serviceAccountUserThe deploy SA itselfLet the build run as the deploy SA rather than the project default
logging.logWriterThe projectRequired because the build writes to Cloud Logging only
iam.serviceAccountTokenCreatorThe deploy SA, granted to Supero's deployer identityThe trust edge — lets Supero impersonate the deploy SA with one-hour tokens

🚨 run.admin is granted on the entire project, unconditioned

The Cloud Run grant is project-wide. Supero's deploy service account can create, update, and delete any Cloud Run service in the connected project, not only the ones it created. This is deliberate and it is a real scope expansion you should weigh before connecting a shared project. The reason: Cloud Run does not evaluate resource.name IAM conditions reliably for run.services.* — a conditioned grant was tried and it denied even resources that matched the condition, so deploys failed outright. If project-wide Cloud Run admin is unacceptable under your policy, connect a dedicated GCP project that contains nothing else. The other seven grants above are scoped to a single resource or, where they are project-wide, are narrow build and logging roles.

💡 The build never acts as your compute default service account

Cloud Build is pinned to run as the scoped deploy service account. That is why the setup grants it serviceAccountUser on itself and logging.logWriter. The project's default compute service account carries the broad Editor role, so allowing Supero to act as it would hand over near-Editor across the whole project — avoiding that is the entire point of the two grants that look redundant.
  • •The External ID from the wizard ties your connect run to this project. Treat the token-creator grant, not the External ID, as the access control: that binding is what governs whether Supero can impersonate the SA at all, and removing it cuts access off immediately.
  • •Revoking is one command — see Teardown below. You do not need to delete any infrastructure to stop Supero reaching your project.

Deploy

Click Deploy. Cloud Build builds the image, pushes it to Artifact Registry, and Cloud Run serves it on a Google-generated *.run.app URL that stays the same across redeploys. Cloud Run scales to zero when idle, so the first request after a pause cold-starts — a few seconds is expected, not a failure.

⚠️ Known issue: a deploy can report success while the URL returns 403

The last step of a GCP deploy grants public invoke access to the Cloud Run service. If that grant fails, the failure is currently swallowed — the service deploys, the phase reaches running, a URL is returned, and anonymous visitors get 403. The symptom is unmistakable: a running deploy whose URL 403s for everyone including you in an incognito window. The fix is to redeploy, or to grant roles/run.invoker to allUsers on that service yourself.

Verify It Actually Works

⚠️ A green status is not the same as a working app

A deploy can report running while serving a blank shell or an empty catalog — the container returns HTTP 200 on the page shell even when it cannot reach your app's data. Walk this checklist once per target before you call a deploy done. A condensed copy lives on the Verification Runbook.
bash
curl -s -o /dev/null -w "GET / -> %{http_code}\n" "https://YOUR-DEPLOY-URL/"
  • •The page loads. HTTP 200, and the landing page renders your app's real branding — not a generic placeholder.
  • •No "couldn't reach the server" banner. If you see one, the container cannot reach Supero's API — redeploy to refresh its runtime credentials, or re-check the Connect step.
  • •A data page shows real records. Open a listing or catalog page and confirm it renders actual records, not empty cards — this proves the namespace and seed data are wired correctly, not just that the container is up.
  • •Sign-up and login work. Create or sign in as an end user; auth proxies to Supero and should succeed exactly as it would on Supero Cloud.
  • •A create persists on reload. Do one write — add to cart, submit a form, create a record — then reload and confirm it is still there. This proves the write path, not just reads.
  • •Open the URL in a private window. On GCP this is the check that catches the swallowed public-access failure described above.

💡 If you deploy to more than one cloud

Run the same checklist against every target — Supero Cloud, AWS, and GCP should all render the same app with the same data, since it is one bundle proxying to the same Supero backend.

Troubleshooting

What you seeWhyFix
Deploy blocked, 402 upgrade promptYour plan has no live-deployment allowance left.Upgrade — live deployments start at Starter. See Plans & Billing.
Deploy blocked, 503The entitlement check could not be completed. This path fails closed on purpose, because a deploy spends money in your account.Retry. If it persists, contact support.
The start call returns 504 but a build appears in your account anywayThe start call is bounded to about 85 seconds so it never hangs behind an edge timeout. The work continues in your cloud.Check CodeBuild or Cloud Build directly, then reopen the panel and redeploy if needed.
The panel lost track of a deploy after a tab reloadThe deploy handle lives in the browser; nothing durable is recorded on the Supero side for customer-cloud deploys.Check the build and the ECS or Cloud Run service in your own console. Tear down anything orphaned before redeploying.
GCP: running, but the URL 403s for everyoneThe public-access grant failed and the failure was swallowed.Redeploy, or grant roles/run.invoker to allUsers on the Cloud Run service.
GCP: a deploy fails partway with a permission errorThe project was provisioned by something other than the current setup script, so it is missing one or more grants.Re-run supero connect-gcp — it is idempotent and re-applies every binding. Do not hand-grant permissions on the default compute service account; it carries Editor, and the setup deliberately avoids it.
AWS: the URL changed after a redeployExpected. The ECS service name carries per-deploy entropy to avoid the roughly one-hour INACTIVE name lock.Read the current URL from the panel after every deploy. Do not publish an AWS deploy URL as a stable address.
AWS: an ECS service shows INACTIVE right after a teardownECS Express holds a torn-down name for roughly an hour.Redeploy immediately — the new deploy gets a freshly salted name, so it does not collide.
AWS: the stack will not createThe stack creates named IAM resources.Tick "I acknowledge that AWS CloudFormation might create IAM resources with custom names" (CAPABILITY_NAMED_IAM), or use supero connect-aws, which passes it for you.
App loads but a data page is empty or genericThe namespace baked into the container does not match the project, or the project was never seeded.Redeploy to refresh the bundle. If it is still empty, open the app once on a Supero Cloud preview so it seeds, then redeploy your cloud target.
Blank shell, or "couldn't reach the server"The running container's scoped runtime key is stale.Redeploy — every deploy mints and injects a fresh scoped read key.

Cost, Logs & Teardown

Cost

Cloud Run scales to zero, so GCP idle cost is close to nothing. ECS Express does not scale to zero — it keeps at least one running task plus a load balancer, so AWS carries a small recurring charge even when nobody is using the app. Both add your own cloud's build-minute and image-storage costs on top. All of it is your cloud bill, not a Supero charge.

Logs

⚠️ The deploy panel does not show build logs for this path

While a customer-cloud deploy is in flight, the panel polls a status endpoint that returns only the phase, the URL once there is one, and an error message on failure. There is no log stream and no log text. To see why a build failed, open CodeBuild or Cloud Build in your own account; for runtime logs, use CloudWatch or Cloud Logging. The in-dashboard Cloud Deploy Logs page reads apps published to Supero Cloud only.

Teardown

  • •Remove deployment in the deploy panel deletes only the running service — the ECS Express service or the Cloud Run service. That is what stops the recurring cloud charge. Your data in Supero is untouched.
  • •AWS — to fully revoke Supero's access, delete the deploy user's access key, or delete the whole CloudFormation stack (which also removes the shared build infrastructure).
  • •GCP — to cut off Supero immediately without touching any infrastructure, remove the token-creator binding from the deploy service account. Optionally remove the rest afterwards: the deploy SA, the runtime SA, the Artifact Registry repo, and the source bucket.
bash
gcloud iam service-accounts remove-iam-policy-binding <deploy_sa_email> \
  --member="serviceAccount:<SUPERO_DEPLOYER_SA>" \
  --role="roles/iam.serviceAccountTokenCreator"

🚨 Teardown does not delete your data

Removing a deployment or revoking access on either cloud only stops the UI container and its cloud cost. Your app's data, schemas, and users stay in Supero regardless of which cloud targets you connect or disconnect. Note the inverse too: taking a Supero Cloud app offline will not tear down a service running in your own account — that record is left intact on purpose, because it is the only pointer to something still billing you.

Next Steps