The trust policy that was one character short
Federated identity replaced the long-lived deploy keys, which was the right move. The role's trust policy names the identity provider and matches the token's subject against a pattern.
The pattern is missing one character. It matches your organisation, and it also matches every organisation whose name merely starts with yours — including one somebody registered last week, which is a name anyone is free to take.
Boundaries, outermost first: Your cloud account: Deploy role (trusts the pattern; FAILED: assumed by both), an empty slot for the what the subject must equal, an empty slot for the what survives a rename Outside every boundary: Your repository (your-org/app), A lookalike owner (your-org-evil/app; FAILED: matches the pattern), Identity provider (issues for both) Connections: Your repository calls Identity provider (step 1) A lookalike owner calls Identity provider — same shape of token (step 2) Identity provider calls what the subject must equal (step 3) what the subject must equal calls Deploy role (step 4) what survives a rename controls what the subject must equal — identity, not name A lookalike owner must NOT reach Deploy role — no longer matches