Delete the audit CFN template that defaults to the vendor's AWS account - #107
Merged
Merged
Conversation
templates/iam.role.audit.account.cfn.yaml defaulted ParentAWSAccountId to 660228977852 -- Teem's own SaaS account -- and built the notifier's ServiceToken from AWS::Region, the child's region, rather than from a parent-region parameter. The sibling child template was fixed to take an explicit ParentDeploymentRegion; this one never was. Deployed with defaults it created a cross-account IAM role in the operator's account trusting an account they do not control, carrying ReadOnlyAccess plus securityhub:*, guardduty:*, macie:*, inspector:*, config:Put*, CloudTrail and CloudWatch Logs writes, and iam:PassRole on role/tops*. Nothing in the product referenced it. install-messaging.sh uploads only iam.role.child.account.cfn.yaml, and TOPS_CFN_TEMPLATE_URL points at that same file, so it was never on the onboarding path -- it was reachable only by a self-hosted operator browsing templates/ and picking the file whose name matched what they wanted. Deleted rather than repaired. A second, unexercised copy of the onboarding template was itself the defect: it drifted through an entire SaaS-to-self-hosted pivot without anyone noticing, because nothing ran it. Repairing it would have restored exactly that condition. templates/sync.sh goes with it. It ran aws s3api put-bucket-acl --bucket storage.teemops.com --acl public-read and synced the whole directory with --acl public-read, which is what made the broken template look canonical -- served from the vendor's domain next to the one that works. Vendor-era publishing has no meaning in a self-hosted install, where the installer uploads the template to the operator's own deployment bucket. That answers the third acceptance criterion on #102: storage.teemops.com should not be publicly readable on this project's behalf, because this project no longer publishes to it. Deleting the script does not un-publish what is already in that bucket. Objects synced there previously stay public until removed by hand. Also drops $topsType from ProcessSqsMessages, assigned and never read. It distinguished "ops" from "audit", and nothing branched on it even while the audit template existed. The installer test now guards the whole templates/ directory against a Default on ParentAWSAccountId, rather than the one file, so a future template cannot reintroduce the defect. Closes #102 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
kiwifellows
force-pushed
the
claude/issue-102-remove-audit-template
branch
from
August 3, 2026 06:13
3279c0e to
05e11b9
Compare
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
templates/iam.role.audit.account.cfn.yamldefaultedParentAWSAccountIdto660228977852— Teem's own SaaS AWS account — and built the notifier'sServiceTokenfromAWS::Region, the child's region, rather than from a parent-region parameter. The sibling child template was fixed to take an explicitParentDeploymentRegion; this one never was.Deployed with defaults, it created a cross-account IAM role in the operator's own account trusting an account they do not control, carrying
ReadOnlyAccessplussecurityhub:*,guardduty:*,macie:*,inspector:*,config:Put*, CloudTrail and CloudWatch Logs writes, andiam:PassRoleonrole/tops*.Closes #102.
Deleted rather than repaired
Nothing in the product referenced it.
install-messaging.shuploads onlyiam.role.child.account.cfn.yaml, andTOPS_CFN_TEMPLATE_URLpoints at that same file — so it was never on the onboarding path. It was reachable only by a self-hosted operator browsingtemplates/and picking the file whose name matched what they wanted.A second, unexercised copy of the onboarding template was itself the defect. It drifted through an entire SaaS-to-self-hosted pivot without anyone noticing, precisely because nothing ran it. Repairing it — dropping the
Default, addingParentDeploymentRegion— would have restored exactly the condition that let it rot: a plausible-looking file that no code path exercises. #102 reached the same conclusion ("most likely just delete it").templates/sync.shgoes with itaws s3api put-bucket-acl --bucket storage.teemops.com --acl public-read aws s3 sync . s3://storage.teemops.com/ --acl public-read ...This is what made the broken template look canonical — served from the vendor's own domain, next to the one that works. A bucket-wide public-read ACL plus a public sync of the whole directory is vendor-era publishing with no meaning in a self-hosted install, where the installer uploads the template to the operator's own deployment bucket.
That answers the third acceptance criterion on #102 — whether
storage.teemops.comshould be publicly readable at all. The recorded decision: not on this project's behalf, because this project no longer publishes anything to it.Also in here
$topsTypedropped fromProcessSqsMessages— assigned and never read. It distinguished"ops"from"audit", and nothing branched on it even while the audit template existed. A comment records that messages still carry the field.templates/directory against aDefaultonParentAWSAccountId, rather than checking one file, so a future template cannot reintroduce the defect.How it was tested
Infrastructure change — no user story.
ParentAWSAccountIdguardreferences/samples/(historical captured SNS messages, which recordTopsAuditSetuprole ARNs as they were and are left as-is) and a gitignored.claude/settings.local.jsonentryQuality gate
sync.shdecisiondocs/practices/Practices check
scan:validate-rulespasses (untouched)Out of scope
storage.teemops.com. Only the bucket owner can do that, and it is not a repo change. Flagged above.TopsMainSQSPolicygrantingSQS:ReceiveMessagetoPrincipal: "*"— the other adjacent finding in the feature doc. Dead permission in practice (theaws:SourceArncondition can never match a direct caller) but it reads badly in review. Not filed yet.🤖 Generated with Claude Code