Filing Guide
Categories:
This page turns the rest of the section into a backlog. It gives you the epic structure, an issue template, and the parameters every issue has to carry.
Start here, in this order
- File the open questions triage ticket first. One ticket, five lookups, an afternoon. Several answers change the shape of epics below, and two of them decide whether a finding is High or Critical. Filing epics before this is filing work you may have to resize.
- File the four Tier 1 fixes as standalone issues, not inside an epic. They are hours of work, they block nothing, and burying them in an epic is how they wait three weeks.
- Then file the nine root-cause epics below.
Doing 2 before 3 matters. The Tier 1 items are cheap and time-sensitive, and epic structure is a planning aid rather than a queue.
The epic structure: nine epics, one per root cause
The root causes page explains why this axis and not another. In short: 142 of the 184 findings map to nine causes, so nine epics carry three quarters of the work, and closing a cause stops the class from regenerating.
| Epic | Root cause | Findings | C | H |
|---|---|---|---|---|
| SEC-E1 | No shared security component | 32 | 0 | 1 |
| SEC-E2 | Hasura admin secret is the only service identity | 8 | 0 | 3 |
| SEC-E3 | Deny-by-default was never adopted | 29 | 2 | 7 |
| SEC-E4 | Boundaries are values inside a request | 20 | 0 | 3 |
| SEC-E5 | No artifact reconciles what exists | 11 | 0 | 1 |
| SEC-E6 | A declared control does not bind | 13 | 0 | 0 |
| SEC-E7 | No enforcement point between change and production | 14 | 0 | 2 |
| SEC-E8 | Nothing observes a security decision | 2 | 0 | 0 |
| SEC-E9 | Credential material has no lifecycle owner | 13 | 0 | 5 |
Plus four from the personal data inventory, which are a different axis over the same estate and should not be folded into the nine:
| Epic | Subject |
|---|---|
| SEC-P1 | Retention exists |
| SEC-P2 | Get personal data out of git |
| SEC-P3 | Coarsen by default on the location paths |
| SEC-P4 | Assert encryption at rest where it matters |
42 findings map to no cause. Do not invent a tenth epic for them. File the ones that matter individually against their component, and let the rest sit in the register until someone has capacity.
Two epics are worth reading before you size any of them
SEC-E3 owns both Criticals and a quarter of all Highs. It is the single highest-value epic in the set.
SEC-E9 produces the second-highest High count from only 13 findings, which makes it the best risk removed per ticket filed on the board. If you have one team and one sprint, this is the one that finishes.
And check Q-12 before writing SEC-E7. If branch protection is genuinely unavailable on the current plan, that epic is a purchasing decision, not engineering work.
Every issue sets five parameters at creation
Not as a follow-up. An issue missing any of these is invisible to whoever is running the board.
- Labels: every applicable label. At minimum
security, the component label, and apriority:*. - Type: the org issue type, Feature, Bug or Task. Set it through the GraphQL
updateIssueIssueTypemutation using node IDs fromorganization { issueTypes }. The RESTtypefield silently no-ops, so a PATCH looks like it worked and does nothing. - Project: add it to the owning org project board and set the Status field (Backlog / Ready / In Progress / In Review / Done). The session
ghtoken usually lacksprojectscope; use a PAT with it. - Milestone: the matching repo milestone.
- Relationship: parent epic via the GraphQL
addSubIssuemutation with theGraphQL-Features: sub_issuesheader, or cross-references in the body where a true parent does not exist.
Labels to use
Reuse the estate’s harmonised set rather than inventing new ones: security, c2pa, mobile, ios, android, enrollment-api, ca, docs, infrastructure, disaster-recovery.
Add one assessment-specific label so the whole body of work stays findable after the epics close: assessment-2026-08.
For severity, use priority:* and map it: Critical to your highest priority, High to the next. Do not create severity labels that duplicate priority, because the two drift and then nobody knows which one the board sorts on.
The Linear mirror
Where work is mirrored into Linear, keep both in lockstep with these equivalents:
| GitHub | Linear |
|---|---|
| Labels | Team labels |
| Type (Feature / Bug / Task) | Type-labels feature / bug / Task |
| Project board + Status field | Native Project + workflow State |
| Milestone | Project Milestones, using the same names as the GitHub milestones |
| Sub-issue | parentId |
| Cross-dependency | issueRelationCreate with type blocks / related / duplicate |
priority:* labels |
Native priority (1 = urgent … 4 = low) |
| Assignee | Assignee |
Reference the GitHub issue URL in the Linear description and the Linear URL in the GitHub issue.
Issue template
Copy this. It is short on purpose.
## Finding
MGR-H11 (High, Verified). Twelve tables grant role user an unfiltered
read, exposing every account's email and the coordinates and media of
unpublished sightings.
Reference: /docs/security/platform-assessment-2026-08/critical-and-high-findings/#mgr-h11
## Location
hasura/metadata/databases/default/tables/public_users.yaml:66
(plus 11 further tables, listed in the finding)
## What is wrong
<two or three sentences, in your own words, from the finding page>
## What to change
<the "what to change" list from the finding page, as checkboxes>
## Done when
<a statement someone can check, not "the fix is merged">
## Blocks / blocked by
Blocked by: #<mobile client query change>
Related: MGR-H07 (same permission class, same repo)
On “Done when”
Write it as something a reviewer can verify by looking at the system, not at the diff. “The permission block no longer has an empty filter” is checkable. “Fixed the over-grant” is not. Several of these findings have a build assertion as their durable fix, and for those the done-when is that the assertion fails on a deliberately reintroduced bad value. If nobody has seen the check go red, nobody knows it works.
Ordering constraints that will bite you
These are dependencies between findings, and they are the reason a naive severity-sorted board goes wrong.
Read this before sequencing anything
The mobile client change ships before the Hasura permission changes. Removing the over-grants in MGR-H07 and MGR-H11 breaks five queries in the shipped mobile client, which depends on the over-fetch. File the mobile change as a blocker on both.
Give the moderator role its permissions before fixing the Cognito group mapping. Staff hold the superuser role in MGR-H20 because the moderator role cannot do the work (MGR-H10). Fixing the mapping alone moves the problem and breaks moderation.
MGR-H17 and MGR-H21 land in one pull request. The scanner-suppression comment on one is written about the scoping the other escapes. Fixing either alone leaves the file asserting a containment it does not have.
Fixing MGR-H11 raises the severity of at least one Low. MGR-L33’s own text says its rating depends on the over-grant remaining in place. Plan for the re-rating rather than being surprised by it.
Two remediation steps in the source are wrong
The assessment’s own handling notes flag two remediation steps that would cost you time if followed literally:
- One names a DNS zone that does not exist.
- One tells you a firewall change will not strand a deploy, when it will.
Neither is identified more precisely than that in the notes available. Treat any remediation step that names a specific DNS zone, or that asserts a firewall or WAF change is deploy-safe, as needing its own verification before you run it. That is a five-minute check against your own accounts and it is cheaper than the alternative.
Evidence links
24 evidence rows across the four committed-credential findings carry a proof URL that does not resolve. If you are chasing a citation on MGR-H01, MGR-H06, MGR-H24 or the fourth in that class and the link is dead, that is a known defect in the source, not evidence that the finding is wrong. Verify against the repository directly.
What not to put in an issue
The handling rules from the section index apply to every ticket you file:
- No credential values. Describe a secret by what it is and where it lives. Never paste one, including into a private issue.
- No personal data rows. Reference a table and a column list; do not paste records.
- No quoting the total outside the team. The 184 is provisional and under revision.
- Do not attribute the work externally. The provenance constraints on the source document have not changed just because the work moved into your tracker.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.