// Task 17a: the cross-account domain claim. Closes the hole review found in // Task 17 — SES identities are per-AWS-ACCOUNT, not per-tenant, so any // domain one CARLOS account verifies is verified globally. Before this, // EnsureDomain computed §4's IAM policy from a domain set that was never // checked for OWNERSHIP: a second account could call EnsureDomain on // "victim.com", get the same identity ARN with no proof of control, and // Enable would hand it a policy granting ses:SendRawEmail with // ses:FromAddress *@victim.com. These tests pin the fix: a create-only, // globally-keyed claim decided BEFORE EnsureIdentity ever runs. package mail import ( "context" "errors" "strings" "testing" "time" "github.com/carlosframework/platform/internal/dnsrec" "github.com/carlosframework/platform/internal/release" ) // A second account claiming a domain the first already holds must be // refused outright: no identity, no domain record. This is the vulnerable // path from Task 17's review, closed. // // ONE SHARED MemProvisioner for both accounts (M2, review follow-up) — this // is the honest model, not two. SES identities are per-AWS-ACCOUNT, and a // CARLOS deployment has exactly ONE underlying AWS account behind it, // shared by every CARLOS tenant account. Two separate MemProvisioner // instances are the one setup that could NOT reproduce the actual bug: each // would let account B mint its OWN identity object in its OWN fake, which // looks like a failure caught (B "got an identity") but proves nothing // about the real defect — in production B would get back the SAME ARN A // already holds, immediately able to send as A's domain with no DNS // control of its own. A single shared provisioner is the only shape where // "B got no identity" actually means what it needs to mean. func TestEnsureDomainRefusesASecondAccountsClaim(t *testing.T) { ctx := context.Background() s, w := release.NewDirStore(t.TempDir()), dnsrec.NewMemWriter() p := NewMemProvisioner("shared-aws-account") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "victimapp", "victim.com", now); err != nil { t.Fatalf("account A's first claim: %v", err) } _, _, err := EnsureDomain(ctx, s, p, w, d, "bbb", "evilapp", "victim.com", now) if err == nil { t.Fatal("account B was allowed to claim a domain account A already holds") } if len(p.Identities) != 1 { t.Fatalf("identities in the shared AWS account = %d, want 1 (A's only) — B must never have reached EnsureIdentity", len(p.Identities)) } if rec, _, err := GetDomain(ctx, s, "bbb", "victim.com"); err != nil { t.Fatalf("GetDomain: %v", err) } else if rec != nil { t.Fatalf("account B got a domain record for a domain it does not own: %+v", rec) } } // The refusal must be a cross-account information leak of exactly nothing: // a losing caller must not learn WHO holds the domain by reading the error. func TestEnsureDomainRefusalDoesNotNameTheHolder(t *testing.T) { ctx := context.Background() s, w := release.NewDirStore(t.TempDir()), dnsrec.NewMemWriter() pA, pB := NewMemProvisioner("A"), NewMemProvisioner("B") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() if _, _, err := EnsureDomain(ctx, s, pA, w, d, "secretacct", "victimapp", "victim.com", now); err != nil { t.Fatalf("account A's first claim: %v", err) } _, _, err := EnsureDomain(ctx, s, pB, w, d, "bbb", "evilapp", "victim.com", now) if err == nil { t.Fatal("expected a refusal") } if strings.Contains(err.Error(), "secretacct") { t.Fatalf("refusal named the holding account: %v", err) } if !errors.Is(err, ErrDomainClaimed) { t.Fatalf("refusal was not ErrDomainClaimed: %v", err) } } // The owning account re-running EnsureDomain on its own claimed domain is // ordinary idempotent success — a claim must never block its own holder. func TestEnsureDomainOwnAccountReRunIsIdempotent(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("A"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() first, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "myapp", "mine.com", now) if err != nil { t.Fatalf("first: %v", err) } second, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "myapp", "mine.com", now) if err != nil { t.Fatalf("second: %v", err) } f, sec := first.Regions["eu-west-1"], second.Regions["eu-west-1"] if f.IdentityARN != sec.IdentityARN || f.DKIMTokens[0] != sec.DKIMTokens[0] { t.Fatal("re-running under the SAME account changed identity/tokens") } if len(p.Identities) != 1 { t.Fatalf("identities = %d, want 1", len(p.Identities)) } } // Teardown of the last app referencing a domain must release the global // claim, and only then — a sibling app still using the domain must keep it // held. Once released, another account can claim it. func TestTeardownReleasesClaimOnlyWhenLastAppGoes(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("A"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "app1", "shared.com", now); err != nil { t.Fatalf("app1 ensure: %v", err) } if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "app2", "shared.com", now); err != nil { t.Fatalf("app2 ensure: %v", err) } // Tear down app1: app2 still references the domain, so the claim must // stay held — a stranger must NOT be able to claim a live domain out // from under a sibling app. if err := Teardown(ctx, s, p, w, d, "aaa", "app1"); err != nil { t.Fatalf("teardown app1: %v", err) } pStranger := NewMemProvisioner("B") if _, _, err := EnsureDomain(ctx, s, pStranger, w, d, "bbb", "strangerapp", "shared.com", now); err == nil { t.Fatal("a stranger claimed a domain still referenced by a sibling app") } // Tear down app2, the last referrer: NOW the claim must release. if err := Teardown(ctx, s, p, w, d, "aaa", "app2"); err != nil { t.Fatalf("teardown app2: %v", err) } rec, _, err := EnsureDomain(ctx, s, pStranger, w, d, "bbb", "strangerapp", "shared.com", now) if err != nil { t.Fatalf("stranger should be able to claim the released domain: %v", err) } if rec == nil || len(pStranger.Identities) != 1 { t.Fatal("stranger did not actually get a fresh identity after the claim released") } } // A platform-suffixed domain is not exempt from the claim gate — one code // path, no special case. (The separate ownership check below this domain // name happens to satisfy — the label matches the caller's own account — // is C1's fix and has its own dedicated tests further down.) func TestEnsureDomainClaimsAPlatformDomainToo(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("A"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "harbourmail", "harbourmail.aaa.oncarlos.com", now); err != nil { t.Fatalf("EnsureDomain: %v", err) } claim, err := getDomainClaim(ctx, s, "harbourmail.aaa.oncarlos.com") if err != nil { t.Fatalf("getDomainClaim: %v", err) } if claim == nil || claim.Account != "aaa" { t.Fatalf("platform domain did not get a claim: %+v", claim) } } // The claim must be the FIRST durable side effect — written before // EnsureIdentity ever runs. Inject a one-shot failure at EnsureIdentity: // the claim must already be there, but no identity was created. A re-run by // the SAME account must then succeed — the claim must not block its own // owner, even though it was written before the walk that owns it finished. func TestEnsureDomainWritesClaimBeforeIdentity(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("A"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() p.FailNext["EnsureIdentity"] = errors.New("SES down") if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "myapp", "mine.com", now); err == nil { t.Fatal("EnsureDomain succeeded despite an injected EnsureIdentity failure") } claim, err := getDomainClaim(ctx, s, "mine.com") if err != nil { t.Fatalf("getDomainClaim: %v", err) } if claim == nil || claim.Account != "aaa" { t.Fatalf("claim missing after the injected failure: %+v", claim) } if len(p.Identities) != 0 { t.Fatalf("identity was created despite the injected failure: %d", len(p.Identities)) } rec, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "myapp", "mine.com", now) if err != nil { t.Fatalf("re-run by the claim's own owner must succeed: %v", err) } if rec == nil || len(p.Identities) != 1 { t.Fatal("re-run did not complete provisioning") } } // ---- C1 (review follow-up): platform names need an ownership check too -- // // §4a originally claimed platform-suffixed names ("..oncarlos.com") // need no ownership check because they are "account-scoped by construction". // That was wrong: DomainKindFor matches only the SUFFIX, and nothing // compared the account label to the caller. Worse than the custom-domain // case the claim alone protects, because CARLOS itself publishes the DKIM, // MAIL FROM and DMARC records — the attacker needs no DNS control at all. // Account bbb must never obtain a platform name that names a DIFFERENT // account's sqid — no identity, no DNS, and (since the check runs before // the claim) no claim left behind either, so a refused attempt cannot even // squat the name for later. func TestEnsureDomainRefusesAPlatformNameForAnotherAccount(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("shared"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() _, _, err := EnsureDomain(ctx, s, p, w, d, "bbb", "evilapp", "harbourmail.aaa.oncarlos.com", now) if err == nil { t.Fatal("account bbb was allowed to claim account aaa's platform name") } if !errors.Is(err, ErrNotOwnPlatformName) { t.Fatalf("err = %v, want ErrNotOwnPlatformName", err) } if len(p.Identities) != 0 { t.Fatalf("an SES identity was created for a platform name bbb does not own: %d", len(p.Identities)) } if len(w.Records) != 0 { t.Fatalf("DNS was published for a platform name bbb does not own: %d records", len(w.Records)) } if claim, err := getDomainClaim(ctx, s, "harbourmail.aaa.oncarlos.com"); err != nil || claim != nil { t.Fatalf("a refused platform-name attempt left a claim behind: %+v", claim) } } // The mirror image: bbb asking for ITS OWN platform name succeeds exactly // as before this fix — the ownership check must not become a second way to // refuse a legitimate member. func TestEnsureDomainAcceptsItsOwnPlatformName(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("shared"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() rec, _, err := EnsureDomain(ctx, s, p, w, d, "bbb", "myapp", "harbourmail.bbb.oncarlos.com", now) if err != nil { t.Fatalf("EnsureDomain: %v", err) } if rec.Kind != KindPlatform { t.Fatalf("kind = %q, want platform", rec.Kind) } } // The bare platform suffix names no account label at all, so no account — // including a well-formed one — can own it. It was accepted before this // fix, and CARLOS would have written a DMARC record at its own zone apex. func TestEnsureDomainRefusesTheBarePlatformApex(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("shared"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() _, _, err := EnsureDomain(ctx, s, p, w, d, "bbb", "myapp", d.PlatformSuffix, now) if err == nil { t.Fatal("the bare platform apex was accepted") } if !errors.Is(err, ErrNotOwnPlatformName) { t.Fatalf("err = %v, want ErrNotOwnPlatformName", err) } if len(w.Records) != 0 { t.Fatalf("DNS was published at the platform's own zone apex: %d records", len(w.Records)) } } // A custom domain names no account label — the ownership check must never // fire for KindCustom, whatever the caller's account is. func TestEnsureDomainCustomDomainUnaffectedByPlatformOwnershipCheck(t *testing.T) { ctx := context.Background() s, p, w := release.NewDirStore(t.TempDir()), NewMemProvisioner("shared"), dnsrec.NewMemWriter() now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() rec, _, err := EnsureDomain(ctx, s, p, w, d, "bbb", "myapp", "example.com", now) if err != nil { t.Fatalf("EnsureDomain on a custom domain was refused: %v", err) } if rec.Kind != KindCustom { t.Fatalf("kind = %q, want custom", rec.Kind) } } // ---- I1 (review follow-up): a stranded claim must actually be releasable - // failDeleteOnce fails the FIRST Delete against one specific key, then // behaves normally — the crash point I1's first strand is about: a failure // between destroying the shared resource (identity/DNS) and deleting the // account's own domain record. type failDeleteOnce struct { release.Store key string failed bool } func (f *failDeleteOnce) Delete(ctx context.Context, key string) error { if !f.failed && key == f.key { f.failed = true return errors.New("bucket delete failed") } return f.Store.Delete(ctx, key) } // Strand 1: a failure deleting the account's own domain record must not // strand the claim. Before I1's fix (release AFTER delete), a crash here // meant the record survived on disk, ListDomains would list it again, but // this exact branch had already tried and failed once — WORSE, if the // record delete itself never succeeds on retry either, the release call // was UNREACHABLE forever, because Teardown's only path to it ran through // a record delete that keeps failing. Releasing FIRST (this fix) means the // claim is gone immediately, regardless of whether the record delete ever // succeeds. func TestTeardownClaimReleaseSurvivesAFailedRecordDelete(t *testing.T) { ctx := context.Background() inner := release.NewDirStore(t.TempDir()) w := dnsrec.NewMemWriter() p := NewMemProvisioner("A") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() if _, _, err := EnsureDomain(ctx, inner, p, w, d, "aaa", "myapp", "mine.com", now); err != nil { t.Fatalf("ensure: %v", err) } s := &failDeleteOnce{Store: inner, key: DomainKey("aaa", "mine.com")} if err := Teardown(ctx, s, p, w, d, "aaa", "myapp"); err == nil { t.Fatal("expected the injected record-delete failure to surface") } if claim, err := getDomainClaim(ctx, inner, "mine.com"); err != nil { t.Fatalf("getDomainClaim: %v", err) } else if claim != nil { t.Fatalf("claim survived a failed record delete: %+v", claim) } // A stranger can claim the domain immediately — no retry required. pStranger := NewMemProvisioner("B") if _, _, err := EnsureDomain(ctx, inner, pStranger, w, d, "bbb", "strangerapp", "mine.com", now); err != nil { t.Fatalf("stranger should be able to claim the released domain: %v", err) } // Retrying the original Teardown (past the one-shot failure) must still // be self-healing, and must not error trying to release a claim it no // longer holds (it's bbb's now). if err := Teardown(ctx, inner, p, w, d, "aaa", "myapp"); err != nil { t.Fatalf("retry did not repair: %v", err) } } // Strand 2: the far more ORDINARY case — EnsureDomain fails after the claim // but before any domain record is ever written (an SES throttle, a tenant // limit, anything). Before I1's fix this was a PERMANENT dead end: // Teardown's domain loop only visits domains with a record, and this one // never got one, so the claim survived every Teardown forever — a global // object no product surface could touch, denying the domain to everyone // including its rightful owner. func TestTeardownReleasesAnOrphanedClaimWithNoDomainRecord(t *testing.T) { ctx := context.Background() s, w := release.NewDirStore(t.TempDir()), dnsrec.NewMemWriter() p := NewMemProvisioner("A") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() p.FailNext["EnsureIdentity"] = errors.New("SES throttled") if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "myapp", "mine.com", now); err == nil { t.Fatal("expected the injected failure") } if claim, err := getDomainClaim(ctx, s, "mine.com"); err != nil || claim == nil { t.Fatalf("claim missing before teardown: claim=%+v err=%v", claim, err) } if rec, _, err := GetDomain(ctx, s, "aaa", "mine.com"); err != nil || rec != nil { t.Fatalf("a domain record exists despite the injected failure: %+v", rec) } if err := Teardown(ctx, s, p, w, d, "aaa", "myapp"); err != nil { t.Fatalf("teardown: %v", err) } if claim, err := getDomainClaim(ctx, s, "mine.com"); err != nil || claim != nil { t.Fatalf("claim survived teardown despite having no record at all: %+v", claim) } pStranger := NewMemProvisioner("B") if _, _, err := EnsureDomain(ctx, s, pStranger, w, d, "bbb", "strangerapp", "mine.com", now); err != nil { t.Fatalf("stranger should now be able to claim the orphaned domain: %v", err) } } // The orphan-reconciliation pass must be scoped to claims with NO record — // it must never touch a sibling app's live, fully-recorded domain, even // though both belong to the same account being torn down. func TestTeardownOrphanReconciliationLeavesRecordedClaimsAlone(t *testing.T) { ctx := context.Background() s, w := release.NewDirStore(t.TempDir()), dnsrec.NewMemWriter() p := NewMemProvisioner("A") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "app1", "live.com", now); err != nil { t.Fatalf("app1 ensure: %v", err) } p.FailNext["EnsureIdentity"] = errors.New("SES throttled") if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "app2", "orphan.com", now); err == nil { t.Fatal("expected the injected failure") } if err := Teardown(ctx, s, p, w, d, "aaa", "app2"); err != nil { t.Fatalf("teardown app2: %v", err) } if claim, err := getDomainClaim(ctx, s, "live.com"); err != nil || claim == nil { t.Fatalf("app1's live claim was released by app2's unrelated teardown: claim=%+v err=%v", claim, err) } if rec, _, err := GetDomain(ctx, s, "aaa", "live.com"); err != nil || rec == nil { t.Fatalf("app1's live domain record was disturbed: %+v", rec) } if claim, err := getDomainClaim(ctx, s, "orphan.com"); err != nil || claim != nil { t.Fatalf("app2's orphaned claim survived its own teardown: %+v", claim) } } // ---- Round 2 (review follow-up): the sweep must not over-release, and -- // ---- must not hand a stranger a live identity ------------------------- // TestTeardownOrphanSweepScopedToTheAttemptingApp (I1 item 1, round 2): an // UNRELATED Teardown for a different app in the SAME account must never // release another app's in-flight claim. The window this closes is not a // microsecond race between goroutines — it is however long the member // takes to retry after a throttle (a quota bump, a support ticket: hours), // and nothing but the App attribution on the claim tells the sweep // "abandoned" from "about to be retried". func TestTeardownOrphanSweepScopedToTheAttemptingApp(t *testing.T) { ctx := context.Background() s, w := release.NewDirStore(t.TempDir()), dnsrec.NewMemWriter() p := NewMemProvisioner("shared") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() // app2 is ordinary and unrelated to the domain under test. if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "app2", "app2-domain.com", now); err != nil { t.Fatalf("app2 setup: %v", err) } // app3 leaves an orphan: claimed, no record — an ordinary retryable // state, not an abandonment. p.FailNext["EnsureIdentity"] = errors.New("SES throttled") if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "app3", "inflight.com", now); err == nil { t.Fatal("expected the injected failure") } // An UNRELATED Teardown, for a DIFFERENT app in the SAME account, must // not touch app3's in-flight claim. if err := Teardown(ctx, s, p, w, d, "aaa", "app2"); err != nil { t.Fatalf("teardown app2: %v", err) } if claim, err := getDomainClaim(ctx, s, "inflight.com"); err != nil || claim == nil { t.Fatalf("app2's teardown released app3's in-flight claim: claim=%+v err=%v", claim, err) } // app3's OWN teardown (a genuine give-up) still releases it. if err := Teardown(ctx, s, p, w, d, "aaa", "app3"); err != nil { t.Fatalf("teardown app3: %v", err) } if claim, err := getDomainClaim(ctx, s, "inflight.com"); err != nil || claim != nil { t.Fatalf("app3's own teardown did not release its orphan: %+v", claim) } } // TestTeardownOrphanSweepDestroysTheIdentityBeforeReleasing (I1 item 2, // round 2): if the crash that orphaned a claim landed AFTER EnsureIdentity // minted a real SES identity but BEFORE any record was ever written, the // sweep must destroy that identity before releasing — otherwise a stranger // who claims the domain next inherits the victim's already-minted ARN and // DKIM tokens with no DNS proof of their own, exactly what the review // demonstrated (stranger inherited ARN=…identity/cust.com, // DKIM=[tokeu1 tokeu2 tokeu3] — the victim's own tokens). func TestTeardownOrphanSweepDestroysTheIdentityBeforeReleasing(t *testing.T) { ctx := context.Background() s, w := release.NewDirStore(t.TempDir()), dnsrec.NewMemWriter() p := NewMemProvisioner("shared-aws-account") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() // SNSTopicARN set, so EnsureConfigSet runs right after EnsureIdentity // Crash AFTER the identity is minted but BEFORE the record is ever // written: EnsureConfigSet is the walk's very next step after // EnsureIdentity, so failing it here reproduces exactly that ordering. p.FailNext["EnsureConfigSet"] = errors.New("SES config set throttle") if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", "victimapp", "cust.com", now); err == nil { t.Fatal("expected the injected failure") } victim, ok := p.Identities[identityKey(d.Region, "cust.com")] if !ok { t.Fatal("test setup: the identity was not actually minted before the injected failure") } victimTokens := append([]string(nil), victim.DKIMTokens...) if rec, _, err := GetDomain(ctx, s, "aaa", "cust.com"); err != nil || rec != nil { t.Fatalf("a domain record exists despite the injected failure: %+v", rec) } if err := Teardown(ctx, s, p, w, d, "aaa", "victimapp"); err != nil { t.Fatalf("teardown: %v", err) } if _, ok := p.Identities[identityKey(d.Region, "cust.com")]; ok { t.Fatal("the orphan sweep released the claim without destroying the live identity") } // A stranger claiming the released domain must get a FRESH identity — // unverified, with NEW DKIM tokens — never the victim's ARN state or // already-issued tokens. rec, _, err := EnsureDomain(ctx, s, p, w, d, "bbb", "strangerapp", "cust.com", now) if err != nil { t.Fatalf("stranger should be able to claim after the sweep: %v", err) } got := rec.Regions[d.Region] for _, tok := range got.DKIMTokens { for _, old := range victimTokens { if tok == old { t.Fatalf("stranger inherited the victim's DKIM token %q", tok) } } } if got.Status != StatusPending { t.Fatalf("stranger's identity status = %q, want pending (unverified) — a fresh identity, not the victim's verified one", got.Status) } } // ---- C1 coverage gap (item 3, round 2): pin equality, not sub/superset -- // TestPlatformNameOwnedByRequiresExactLabelEquality pins platformNameOwnedBy's // comparison as EQUALITY — neither a HasSuffix nor a HasPrefix substitution // may pass this table. Also covers the bare-apex early return with an // account name ("com") chosen specifically so the FALLBACK label-extraction // logic would otherwise (wrongly) accept it — deleting the early-return // guard is invisible against every OTHER case in this file, because the // fallback happens to compute "com" from the apex and no other test // account is named that. func TestPlatformNameOwnedByRequiresExactLabelEquality(t *testing.T) { d := testDeployment() // PlatformSuffix = "oncarlos.com" cases := []struct { name string domain string acct string want bool }{ {"exact label match", "x.aaa.oncarlos.com", "aaa", true}, {"caller is a strict prefix of the real label", "x.aaa.oncarlos.com", "aa", false}, {"caller is a strict superset of the real label", "x.aa.oncarlos.com", "aaa", false}, {"bare apex refused even for the account named after the fallback's own tail label", d.PlatformSuffix, "com", false}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { if got := platformNameOwnedBy(d, c.domain, c.acct); got != c.want { t.Fatalf("platformNameOwnedBy(%q, %q) = %v, want %v", c.domain, c.acct, got, c.want) } }) } } // TestTeardownOrphanSweepDoesNotCrossAccountsOnAMatchingAppName (round 3, // review follow-up): the sweep's filter is `c.Account != acct || // c.App != app` — BOTH halves ANDed together, not App alone. App names are // short, common words, so two DIFFERENT accounts sharing one (e.g. both // running an app called "web") is entirely plausible. If the Account half // ever regressed out, the sweep would read GetDomain under the WRONG // account, find nothing (domain records are account-keyed), conclude // "orphan", and call DeleteIdentity on a domain ANOTHER account has // live — destroying it — with releaseDomainClaim's own owner check only // then quietly no-op'ing the claim removal itself. The destructive // DeleteIdentity call happens BEFORE that guard, so the identity is gone // regardless. This test sets up exactly that shape (two accounts, the // SAME app name) and asserts account B's Teardown is a complete no-op // against account A's orphan: claim intact, identity intact. func TestTeardownOrphanSweepDoesNotCrossAccountsOnAMatchingAppName(t *testing.T) { ctx := context.Background() s, w := release.NewDirStore(t.TempDir()), dnsrec.NewMemWriter() p := NewMemProvisioner("shared") now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) d := testDeployment() const sameApp = "web" // Account A leaves an orphan under app "web": claimed, identity // minted, no record — the crash-after-EnsureIdentity shape item 2 // (round 2) closed for the SAME account/app; this test is about a // DIFFERENT account reaching it. p.FailNext["EnsureConfigSet"] = errors.New("SES config set throttle") if _, _, err := EnsureDomain(ctx, s, p, w, d, "aaa", sameApp, "orphaned-by-a.com", now); err == nil { t.Fatal("expected the injected failure") } if _, ok := p.Identities[identityKey(d.Region, "orphaned-by-a.com")]; !ok { t.Fatal("test setup: account A's identity was not actually minted") } if rec, _, err := GetDomain(ctx, s, "aaa", "orphaned-by-a.com"); err != nil || rec != nil { t.Fatalf("a domain record exists despite the injected failure: %+v", rec) } // Account B, a totally unrelated account, happens to name its own app // "web" too and tears it down. This must be a complete no-op against // account A's orphan. if err := Teardown(ctx, s, p, w, d, "bbb", sameApp); err != nil { t.Fatalf("teardown bbb/%s: %v", sameApp, err) } if claim, err := getDomainClaim(ctx, s, "orphaned-by-a.com"); err != nil || claim == nil || claim.Account != "aaa" { t.Fatalf("account B's teardown disturbed account A's claim: claim=%+v err=%v", claim, err) } if _, ok := p.Identities[identityKey(d.Region, "orphaned-by-a.com")]; !ok { t.Fatal("account B's teardown destroyed account A's LIVE identity on a matching app name") } }