import { type Result } from "@fjall/generator"; /** * A single secret/parameter the build needs to read, normalised from either a * `docker.buildSecrets` ref or a sourced `docker.buildArgs` value. Exactly one * of `ssm` / `secretsManagerName` / `secretsManagerArn` is set; `env`-sourced * values never reach here (they read host env, not AWS). */ export interface BuildSecretRef { ssm?: string; secretsManagerName?: string; secretsManagerArn?: string; } export interface BuildSecretSessionContext { appName: string; region: string; accountId: string; partition: string; } /** * The binding STS limit on an inline session `Policy` is NOT the documented * 2048-char plaintext cap — it is the PACKED (compressed binary) budget that * the policy shares with session tags, and for high-entropy ARN content it * binds far earlier. Measured against STS on 2026-08-23 (dev account, * us-east-2): 117 chars packed to 9%, 720 chars to 64%, and the * `AssumeRoleWithWebIdentity` boundary for `buildDeploySessionPolicy` output * sat between 1255 chars (accepted) and 1258 chars (PackedPolicyTooLarge). * That knife edge is what silently killed every nightly deploy-test mint from * 2026-08-10 — the policy passed the old 2048 plaintext guard and died at STS. * * 1190 leaves ~5% headroom under the measured boundary while admitting the * maximal CANONICAL app name: the deploy policy serialises to BASE + * pascalLen + 2 * kebabLen chars, and over the kebab namespace the generator * scaffolds that maximises at the 50-char hyphen-free name (~1164 chars with * the account-pinned ECR entries). Degenerate legacy-Pascal names whose kebab * expansion overflows this (e.g. "aB" * 25 → ~1214) fail closed with the * budget named — they could never deploy anyway (pre-fix they died at STS * with an opaque PackedPolicyTooLarge), and admitting them would mean * sailing ~3% under the measured cliff. We fail closed here, before minting * a session whose policy STS would reject, rather than ship a * silently-broadened or truncated policy. Shared by all three session-policy * builders (`deploySessionPolicy.ts`, `domainSessionPolicy.ts`, and this one) * — they guard the same STS budget. */ export declare const MAX_PACKED_SAFE_POLICY_CHARS = 1190; /** * Derive the `aws` / `aws-cn` partition from a region. China regions use the * `aws-cn` partition; everything else (incl. GovCloud `us-gov-*`, which is * still `aws-us-gov` — out of scope here, callers pass it explicitly) is `aws`. */ export declare function partitionForRegion(region: string): string; /** * Build a least-privilege inline session policy scoping a build identity down to * exactly the SSM parameters and Secrets Manager secrets a build reads. The * baseline grants the app's own prefix (`parameter//*` and * `secret:fjall--*`); any ref ARN that falls OUTSIDE that prefix is * added as an explicit resource so cross-app shared secrets still resolve. * * Fails closed when the serialised policy would exceed the AWS inline-policy * limit — a build with that many out-of-prefix refs must be split rather than * granted a widened scope. * * SECURITY: the SM ARN baseline ends in `-*` (never a bare `*`) so the wildcard * consumes only the AWS-generated 6-char suffix, not sibling secrets — see * generator-standards.md "IAM Secrets Manager ARN scoping". */ export declare function buildBuildSecretSessionPolicy(ctx: BuildSecretSessionContext, refs: readonly BuildSecretRef[]): Result;