Entitlements & token security

This page is the reference for how StrataBI Enterprise authorizes a licensed install: how your entitlement is proven, how the install runner knows it is permitted to deploy, where secrets live, and what the trust boundaries are. It is written for the security and DevSecOps reviewers who need to sign off before StrataBI runs in your account.

The short version: Shaleio never holds credentials in your account, and the control plane never receives yours. Every deploy runs in your AWS account, under your own IAM identity, against state in your own S3 bucket. The control plane (StrataHQ) is a request/response entitlement service — it answers "is this account licensed for this version?" and, if so, hands back a short-lived, signed pointer to the artifact. Nothing more.

The actors

ActorWhere it runsCredentials it holds
Operator (you)Your workstation / CIYour own AWS identity; the license token
StrataCTLSame as the operatorNone of its own — uses the operator's identity
StrataCI runnerEphemeral compute in your accountA CodeBuild service role in your account (or your CI's role)
StrataHQShaleio's control-plane accountNone in your account; cannot assume into it

StrataHQ is reachable only over HTTPS at the entitlement endpoint. It is the only Shaleio component in the picture, and it is contacted twice at most per install: once to check the entitlement, once to download the artifact over the presigned URL it returns.

Two independent gates

A licensed install (install-stratabi, update, fetch-runtime) calls POST /entitlement on StrataHQ. The request passes two checks that both have to succeed.

1. Caller-account proof (SigV4 / IAM)

The entitlement endpoint is IAM-authorized. StrataCTL signs the request with SigV4 using your AWS credentials, and API Gateway verifies that signature before the Lambda ever runs. The handler then reads the caller's AWS account id from the verified request context (requestContext.identity.accountId) — not from anything the client puts in the body.

The practical consequence: the account identity is cryptographic, not asserted. If the request body claims a customer_id that disagrees with the SigV4-verified account, the request is denied. A license token is therefore only redeemable from the AWS account it was issued for — copying it to another account gets you a 403, because that account's signature won't match the licensed one.

Note. The signing uses botocore's own HTTP path so the exact bytes and headers that were signed are what travel on the wire; the license token rides in the X-Strata-Token header specifically so the Authorization header is left free for the SigV4 signature.

2. License-token gate

The token is checked against the entitlement store for the verified account. StrataHQ stores only the SHA-256 of your token, never the token itself; the handler hashes the presented token and compares it to the stored token_sha256, and requires the record's status to be active. A missing, unknown, revoked, or inactive token yields the same uniform denial as any other failure.

Only after both gates pass does the entitlement check proceed to resolve the version.

What a denial looks like

Every failure path returns a uniform 403 with no detail about why. This is deliberate: the response never reveals whether a module or version exists, so an unlicensed caller cannot probe the catalog. install/update require an active, unexpired grant. destroy is treated specially — see below.

What an allow returns

On success StrataHQ returns a small JSON document:

FieldMeaning
artifact_urlA short-lived presigned GET URL for the exact artifact (default TTL 900s / 15 min)
sha256The expected SHA-256 of the bundle
signatureA KMS signature over that SHA-256 (base64)
versionThe resolved version (e.g. latest → 1.7.1)
expires_atWhen the presigned URL stops working

The presigned URL is generated with SigV4 (s3v4) so it can read the SSE-KMS-encrypted artifact. It is single-object, read-only, and expires quickly.

How the runner knows it is permitted

The runner does not make its own licensing decision. It is handed, by the operator's already-authorized StrataCTL invocation, a short-lived presigned URL that only an entitled caller could have obtained. Possession of that URL is itself the proof that the entitlement check passed. The runner then independently establishes two more things before it applies anything:

  1. Authenticity + integrity. It downloads the bundle, recomputes the SHA-256, and verifies the KMS ECDSA-P256 signature over that hash offline, against a public key pinned in your StrataCTL config (STRATA_HQ_PUBKEY). With STRATA_REQUIRE_SIGNATURE=1 an unsigned or unverifiable bundle aborts the run. This means even a leaked presigned URL, a poisoned cache, or a tampered S3 object cannot inject altered Terraform — the signature won't verify.
  2. Account self-check (replay protection). The runner calls sts:GetCallerIdentity and compares the account it is actually running in to the licensed account passed in the job spec (STRATA_CUSTOMER_ID). If a job spec were copied and replayed into a different account, the runner refuses and marks the job failed.

Put together: the presigned URL proves entitlement, the signature proves authenticity, and the self-check proves the right account — three independent properties, no single point of trust.

Module order forms

For Official Modules (not the platform itself), the same install/update call also records a per-account order form: StrataCTL shows you the module's license terms, you accept once, and StrataHQ stores an account-stamped record. The license is a perpetual, per-account run right — modules you install keep running even if Premier lapses — while Premier is what gates extraction and updates. See Module order forms for the terms, the recorded fields, and how to review them.

Teardown is never trapped

destroy / uninstall is always permitted. For a destroy action StrataHQ will serve the retained artifact even if the grant has lapsed, expired, or the version has been retired — the grant must still exist (you were legitimately entitled at some point), but it need not be active. With the default local delivery the bundle is already cached in your own bucket and re-verified offline, so teardown does not depend on Shaleio connectivity at all. See Delivery & teardown.

Retrieving entitlement without CodeBuild

The same entitlement check is available to pipelines that don't use StrataCI at all. Two StrataCTL commands expose it directly, with no bootstrap and no CodeBuild:

Both run the identical two-gate check described above — SigV4 account proof and license-token gate — and return the identical signed, short-lived pointer. Nothing about the authorization is weaker than the installer path; only the execution moves into your pipeline. The security properties stay layered and distinct:

LayerWhat it provesWhere it's checked
License tokenYou hold a valid, active licenseStrataHQ (SHA-256 compare)
AWS SigV4 identityThe request comes from the licensed accountAPI Gateway + StrataHQ
Presigned URLThe entitlement check passed (short-lived bearer)Possession proves it
SHA-256The bytes weren't altered in transit/at restYour side (fetch-bundle)
KMS signatureThe artifact is authentic Shaleio contentYour side, offline, against the pinned key
Deployment accountOpenTofu runs in the right accountYour pipeline (the runner's self-check is not in this path)

The 15-minute expiry applies to the presigned artifact URL, not to your license — the license is perpetual for the versions it covers (see the licensing terms). Resolve or fetch close to when you deploy; don't store the URL.

See Bring your own CI/CD for the full workflow.

Secret handling

SecretWhere it comes fromHow it is storedLifetime
License tokenSTRATA_HQ_TOKEN, your config file, or SSM /strataci/hq/tokenAt StrataHQ: SHA-256 only. On your side: wherever you choose to keep itLong-lived until rotated/revoked
Presigned artifact URLReturned by the entitlement checkNot persisted≤ TTL (default 15 min)
HQ public keyPinned in your StrataCTL configPlain config value (it is public by nature)Static

StrataCTL and the runner treat the presigned URL and the token as sensitive: a single module declares which environment keys are secret, and those values are never printed and are scrubbed from any error text before it reaches a log or the jobs table.

Residual exposure, stated plainly. When the runner runs in the built-in CodeBuild plane, the presigned URL is passed as a plaintext build environment override, so it is visible in the build's environment metadata to principals inside your own account who can read CodeBuild. We accept that residual exposure because the value is ephemeral (≤ the presign TTL), single-object, read-only, and confined to your account. If that is not acceptable for your threat model, run the install in your own CI with your own secret handling — see Bring your own CI/CD.

Least-privilege credential model

The install plane separates three identities so no single one is both human-held and broadly privileged:

All of these live in your account and are created by stratactl bootstrap; you can read the exact Terraform before you apply it. See the StrataCI reference for the full resource list.

What Shaleio can and cannot do

CanCannot
Answer whether an account+version is entitledAssume a role in your account
Serve a short-lived, signed artifact pointerRead your data, state, or logs
Revoke a token (future installs stop)Reach into or modify a running deployment
Retire a version in the catalogPrevent you from tearing down what you installed

Because every deploy runs under your identity against your state, revoking a token stops future installs and updates but cannot touch what is already running — that remains entirely yours to operate or remove.

Reviewer checklist