Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,8 @@ These are public, tracked, and being worked on. Reporting them again is not a fi

| | |
| --- | --- |
| [#101](https://github.com/teemops/tops/issues/101) | The parent account's `teemops-sns` topic accepts `sns:Publish` from any AWS principal. Publish-only, and acting on a message still requires guessing a 122-bit `external_id`, but it is open and it is being fixed. The issue links the full research and the options considered |
| [#100](https://github.com/teemops/tops/issues/100) | The account-linking consumer does not cross-check the account in `TopsRoleArn` against the one in `StackId`, nor require a `pending` status |
| [#102](https://github.com/teemops/tops/issues/102) | `templates/iam.role.audit.account.cfn.yaml` defaults to a vendor AWS account and is not on the onboarding path |
| [#101](https://github.com/teemops/tops/issues/101) | The parent account's `teemops-sns` topic accepts `sns:Publish` from any AWS principal. The subscription now screens messages on a per-install id and quarantines the rest, so a forged publish does not reach the queue — but the topic itself is still openly publishable, and the issue stays open until that is closed off. Background: [`docs/features/sns-topic-publish-authorization.md`](docs/features/sns-topic-publish-authorization.md) |
| [#109](https://github.com/teemops/tops/issues/109) | The `teemops_main` queue policy grants `SQS:ReceiveMessage` to `Principal: "*"`. The `aws:SourceArn` condition means it cannot actually authorise a direct caller, so it is dead permission rather than exposure — but it is known, and being removed |

## Supported versions

Expand Down
14 changes: 6 additions & 8 deletions design/docs-site/information-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ somewhere and needs porting and a change of voice, not that a `user-docs/` page
| **Security** |
| The security model | Evaluator | ✅ **Built this session** | The architecture page's boundary table | **1** |
| Where your data lives | Evaluator | ✍️ Write | Nothing leaves the install — needs stating plainly | 2 |
| Reporting a vulnerability | Evaluator | ✍️ Write | No `SECURITY.md` exists — **gap** | **1** |
| Reporting a vulnerability | Evaluator | ✅ **Done** | `SECURITY.md` — link to it rather than restating it | **1** |
| Licence and trademark | Evaluator | ✅ Exists | `LICENSE`, `TRADEMARK.md`, roadmap D-7 | 3 |
| **Reference** |
| Glossary | All | ✅ Exists | `docs/GLOSSARY.md` | 3 |
Expand All @@ -164,13 +164,12 @@ job, which is the argument for doing the IA before the writing.

### Two gaps this inventory exposed

1. ~~**There is no `SECURITY.md`.**~~ **Written 2026-08-02.** A public repo with a `security`
1. ~~**There is no `SECURITY.md`.**~~ **Closed 2026-08-03.** A public repo with a `security`
label, three open security issues and a CISO-facing architecture page had nowhere to
report a vulnerability, and `README.md` said "open an issue" — precisely the wrong advice.
Now at the repository root, with the README pointing to it. **Two follow-ups it depends
on:** GitHub private vulnerability reporting must be enabled (it is currently off), and
`security@teemops.com` must be created and routed. Until both are done the policy names
channels that do not answer.
`SECURITY.md` is now at the repository root with the README pointing to it, GitHub private
vulnerability reporting is enabled, and `security@teemops.com` is routed. Both channels the
policy names now answer.
2. **`docs/quick-start.md` is dead.** It describes a Nuxt 3 + Serverless + Prisma monorepo —
the pre-pivot stack. It is linked from `docs/README.md` and would mislead anyone who found
it. Delete it rather than port it.
Expand Down Expand Up @@ -246,8 +245,7 @@ against the roadmap — the roadmap describes intent, `PROGRESS.md` describes th
Priority in the inventory says what matters; this says what unblocks what. Roughly dependency
order, not importance order.

1. **`SECURITY.md`** — repo hygiene, blocked by nothing, and the one gap with an active
reason to exist today.
1. ~~**`SECURITY.md`**~~ — done 2026-08-03, with both reporting channels live.
2. **The two evaluator pages** — already written. *How TOPS connects to AWS* is done; *What
the IAM role can do* is a straight extraction from it and the child template.
3. **Reading a finding**, then **Resolving a finding.** In that order: resolution is
Expand Down
11 changes: 7 additions & 4 deletions user-docs/start-here/how-tops-connects-to-aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ alone. The administrator creates the stack in their own console, under their own

[![Diagram: TOPS generates a CloudFormation quick-create URL; the child account admin creates a stack that makes a cross-account IAM role plus a custom resource; the custom resource publishes the role ARN to the parent SNS topic; the TOPS worker long-polls SQS, matches it and stores it, then replies to CloudFormation.](../assets/diagrams/aws-child-account-linking.svg)](../assets/diagrams/aws-child-account-linking.svg)

1. **Hand over a link.** A console quick-create URL carrying four parameters: your parent
account id, the region, the account's `ExternalId` and its `UniqueId`.
1. **Hand over a link.** A console quick-create URL carrying five parameters: your parent
account id, the region, the account's `ExternalId`, its `UniqueId`, and a `TopsInstallId`
that identifies your installation.
2. **The admin creates the stack.** In their account, with their permissions. TOPS has no
session there and cannot create it for them.
3. **The stack calls home.** A custom resource publishes the new role ARN, external id and
unique id to your SNS topic, which fans into `teemops_main`.
3. **The stack calls home.** A custom resource publishes the new role ARN, external id,
unique id and install id to your SNS topic. The topic's subscription only forwards
messages carrying *your* install id into `teemops_main`; anything else goes to a
quarantine queue you can inspect, so a mismatched link fails visibly instead of silently.
4. **Your worker picks it up.** Outbound long-poll from inside your network. The message is
accepted only if both ids match a record you already created.
5. **The stack completes.** TOPS replies to the CloudFormation `ResponseURL`; the admin sees
Expand Down
Loading