Skip to content

feat: serve SecurityReport and SecurityAcknowledgement - #28

Open
mattdjenkinson wants to merge 1 commit into
feat/submissionsfrom
feat/security-reports
Open

mattdjenkinson wants to merge 1 commit into
feat/submissionsfrom
feat/security-reports

Conversation

@mattdjenkinson

Copy link
Copy Markdown
Contributor

Serves SecurityReport, SecurityAcknowledgement and submissions/{name}/to-security-report. Closes #9.

Stacked on #27 (submissions), which is on #26, #25, #23, #22 and #16. With this, every resource in the design is served.

Security reports

  • Reporters create reports in the user context:
    • verified email required, with the same per-user limit as submissions;
    • names are generated as sec-…, unique across reporters;
    • they read their own reports without status.internal, can't change or withdraw them, and can't set spec.reporter.
  • External reports: the Security Team logs reports from email or GitHub in the platform context, and spec.reporter is required there. These belong to the platform scope, through a new pg.Kind.CreateScope, so staff can still read every report while external ones have no user owner. They show as external in kubectl get securityreports -o wide. Attachments can't be added to logged reports, because uploads are user-context only.
  • Status is written only by the Security Team, never by sync or the controller:
    • a phase change with no timeline entry for it gets one, so the reporter always sees it;
    • timeline entries can be added but not changed or removed;
    • checked: phase, severity, CVSS vector format, reason for NotApplicable and Duplicate, internal.duplicateOf for Duplicate (and not itself), a credits reward amount, and an https advisory URL.
  • Attachments are AttachmentUploads with purpose: SecurityReport, stored under their own prefix. A submission upload can't be attached to a report. securityreports/{name}/attachment?ref= serves files to the reporter and the Security Team, sharing the download code with submissions.
  • Never embedded, indexed, synced or sent to the AI gateway: nothing here calls those paths. Metadata-only auditing is Audit backend #11.

SecurityAcknowledgement

A read-only get and list view of reports in Fixed or Disclosed whose reporter chose public credit with a name. It holds only the credited name, link, month fixed (from the first Fixed timeline entry, else Disclosed) and severity, newest first. The list is small, so it isn't paged and supports no selectors except metadata.name.

to-security-report

Staff (platform context, not sync or the controller) POST a SubmissionToSecurityReport to a submission that is still PendingReview. In one transaction:

  • a report owned by the submitter is created from the title, body and context, plus the optional affected;
  • the attachments are copied to the report's prefix;
  • the submission is deleted, which deletes the original files.

The response is the new report. Dry run is refused, since copying files is a side effect.

For #10

The Security Team needs its own Milo role with securityreports (including status and attachment) separate from the feedback reviewer role. The feedback reviewer role needs submissions/to-security-report and must not get securityreports. The datum.net service account needs securityacknowledgements get and list.

Testing

  • Postgres integration tests:
    • Reporter path: generated names, server-set status, isolation between users, owner annotation, every rejected create (reporter from user, unverified, bad credit URL, public credit without a name, org context), no update, delete or status writes by reporters, rate limit.
    • Security Team status: auto timeline, notes kept rather than doubled, the reporter's redacted view, seven invalid updates, sync refused, credits reward.
    • External reports: platform scope; a reporter is required; sync can't log one; users don't see them.
    • Acknowledgements: only fixed or disclosed reports with public credit; month from the Fixed entry; ordering; Get on hidden reports returns NotFound.
    • Attachments: wrong purpose refused; metadata taken from the upload; downloads by reporter, team and others.
    • to-security-report: submitter and controller refused; report fields and owner; submission gone; the reporter reads the report and the moved file; the original file deleted; a reviewed submission returns Conflict.
  • Kind cluster:
    • Alice's report with an attachment;
    • the team triaged it with internal notes, which Alice's view hid, and the timeline was appended;
    • Alice downloaded the file, and Bob got NotFound;
    • an external report was logged;
    • Fixed made the acknowledgement appear for the datum.net stand-in with only the four fields;
    • a staff move of Bob's submission returned a report owned by Bob, the submission was gone, and Bob saw the report.

- Reporters create reports in the user context and read their own without
  status.internal. Names are generated; verified email and the submission
  rate limit apply. Attachments use SecurityReport uploads under their own
  prefix, served by securityreports/{name}/attachment.
- The Security Team logs reports for external reporters in the platform
  context (spec.reporter required); those belong to the platform scope via
  a new pg.Kind.CreateScope.
- Only the Security Team writes status, never sync or the controller. Phase
  changes always get a timeline entry, entries are append-only, and reason,
  duplicateOf, CVSS, reward amounts and advisory URLs are validated.
- SecurityAcknowledgement is a read-only view of Fixed or Disclosed reports
  with public credit: name, link, month fixed, severity.
- submissions/{name}/to-security-report moves a pending submission to the
  security track in one transaction: a report owned by the submitter,
  copied attachments, and the submission deleted.
- The attachment download subresource is shared by both kinds.

Part of datum-cloud/enhancements#943. Closes #9.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant