Skip to content
CommonLayer
Documentation menu
On this page

Privacy rules

CommonLayer publishes a lot on purpose: funding flows, maintainer compensation by slot, eligibility states, security findings and exceptions. It never publishes personal and payment data, private security information or anything a person marked as anonymous or private. This page lists what is public and what never is, area by area, matching the public projection types in the code, which are the single implementation of these rules.

How the rules are implemented

  • Anonymous reads go through separate service methods named *_public that take no actor and return dedicated public types. Every other method requires an authenticated actor and a permission (ADR-0006).
  • Private fields are not filtered out of a shared type at the edge; they are absent from the public type. Tests serialize public responses and assert that private values do not appear (for example contributions::guests_and_anonymity_never_leak_into_public_projections in crates/commonlayer-funding/tests/it/contributions.rs, http::public_routes_answer_anonymously_with_public_projections in crates/commonlayer-maintenance/tests/it/http.rs, projects::public_projection_contains_no_private_fields in crates/commonlayer-projects/tests/it/projects.rs).
  • Non-public resources answer 404 to people who may not know they exist.
  • Logs never contain passwords, tokens, cookies, authorization headers, CSRF values, webhook secrets, signing keys, payment payloads, billing data, security-report contents or full SBOMs; audit diffs mask secret-named keys.

What is public and what never is

AreaPublicNever publicPublic type
Usersusername, display name, avatar, bio, website, account kind, member since; approved public contributionsemail, sessions, tokens, linked identities, private follows, notification settingsPublicUserResponse (crates/commonlayer-auth/src/http/dto.rs)
Organizations (only when is_public)slug, name, description, website, logo, creation date; the organization's name as display name on its non-anonymous contributionsmembers, invitations, internal notes, billing profile, service accounts; private organizations answer 404PublicOrganization (crates/commonlayer-organizations/src/service/model.rs)
Organization funding (only for public, active organizations; GET /organizations/{slug}/funding)totals per currency of confirmed, non-anonymous contributions net of refunds, the infrastructure part, active non-anonymous monthly commitments; funded public projects with amount, number of contributions and whether the organization sponsors them nowanything given anonymously (left out entirely, so the totals never reveal it), projects that are not public, payment references, the members who paid, the billing profileOrganizationFundingPublic (crates/commonlayer-funding/src/service/read.rs); test wp70::organization_checkout_covers_projects_and_infrastructure_like_the_personal_one
Contribution status by token (GET /funding/checkout/status with X-Status-Token)to the holder of the token only: status, kind, provider, gross and refunded amounts, items with project slug and name, receipt number once confirmedthe payer's name, email, message, organization, provider reference, failure detail; the token itself is stored only as a SHA-256 hash and never written to the idempotency recordContributionStatusPublic (crates/commonlayer-funding/src/service/contributions.rs); test wp70::a_guest_follows_their_payment_with_the_status_token
Projects (public lifecycle states)metadata, upstream and license, lifecycle, funding and security states, supported versions and architectures, documents, repository URL, release and build datesproposals in proposed, in_review or rejected state (404 to outsiders); the private section (manifest status, review notes) for holders of project.read_privateProjectPublic (crates/commonlayer-projects/src/dto.rs)
Project fundingtarget, coverage, funding state, balance of each account kind, refundable balance, reserve runway, active and past allocation policies, campaignspayment references, provider ids, fee details per payerProjectFundingPublic, BalancesView (crates/commonlayer-funding/src/service/read.rs)
Contributions (money)amount to the project, currency, confirmation date, display name unless anonymous, message if given, whether recurringthe name of anonymous contributors (also hidden from the organization and user attribution), emails, billing details, provider references, guest identitiesPublicContribution (crates/commonlayer-funding/src/service/read.rs)
Project ledgertransaction kind, description, date, entries by account kind and amounttransaction metadata, the acting userTransactionView without metadata and actor_type (crates/commonlayer-funding/src/service/ledger_admin.rs)
Monthly cyclesevery cycle line: slot, payee username, planned and allocated amount, outcome (paid into obligations, held, forfeited, vacant, swept), destination, obligation status, explanationpayout destinations, tax status, bank details, the evaluation's private evidenceCycleLineView (crates/commonlayer-funding/src/service/cycles.rs)
Community rewardsrecipient username, amount, rationale, status, approvals count, datesapprovers' private notes; the recipient's payout destinationRewardView (crates/commonlayer-funding/src/service/rewards.rs)
Infrastructure treasuryallocations and recorded expenses with category and descriptionvendor account detailsInfrastructureReport (crates/commonlayer-funding/src/service/infrastructure.rs)
Maintainerspublic bio and links, approval date, assignments (project, role, period), assignment historypayout destination, tax status, application notes, suspensions' reasons, agreements' acceptance IPPublicMaintainerView, PublicAssignmentEvent (crates/commonlayer-maintenance/src/service/views.rs)
Maintenance tasks (GET /projects/{slug}/maintenance-tasks)kind, title, period, due date, whether required, status, completion date, evidence links not marked privateevidence marked private, waiver reasons, assignees, finding references; security-acknowledgement tasks are left out entirely because their findings may be embargoedPublicTaskView (crates/commonlayer-maintenance/src/service/listings.rs); test wp70::the_public_task_list_hides_private_evidence_and_waiver_reasons
Maintenance agreement (GET /maintenance/agreement)the current agreement's title, version, text and SHA-256who accepted it and from whereAgreementText (crates/commonlayer-maintenance/src/service/listings.rs)
Eligibilityper period and active assignment: state, whether final, whether overridden, the rule summary, an explanation without private identifiersstored inputs, evidence marked private, CVE identifiers of embargoed findings, appeals and their statements, override reasonsPublicEvaluationView (crates/commonlayer-maintenance/src/service/views.rs)
Securityfindings on public projects once not embargoed, their timelines, exceptions with justification, VEX statements, advisories, scan history, digest vulnerabilities, public incidentsembargoed findings, private reports and their messages (encrypted at rest; visible only to the reporter, holders of project.security.read_private and platform.security.manage), draft advisories, non-public incidentscrates/commonlayer-security/src/service/reads.rs
Artifactsartifacts, versions, digests, tags, platforms, signatures, attestations, SBOMs, verification checks and policy, verification commands, releases, builds; for a failed scan gate only the number of blocking findings (security review MEDIUM-7)submissions and pipeline history (project members only); the ids of blocking findings, which may be embargoedcrates/commonlayer-artifacts/src/service/catalog.rs
Pull statistics (GET /projects/{slug}/artifacts/{name}/pulls, gRPC GetPullStats)pulls per artifact and day, zero-filled, 1–365 dayswho pulled, client addresses, individual pull eventsPullStats (crates/commonlayer-registry/src/service/pulls.rs)
Abuse reportsnothingevery report: visible to its reporter (GET /users/me/abuse-reports) and to platform administrators; the reported person or organization is not told who reported themcrates/commonlayer-organizations/src/service/abuse.rs
GitHubpull requests tracked for public projects (not those of private repositories)delivery payloads and logscrates/commonlayer-github/src/service/queries.rs

Where the implementation differs from the original plan

  • The plan lists an organization's "funded projects and totals" as public when the organization is public. They are, since WP-70b, with one restriction the plan did not state: anonymous contributions are left out of the totals entirely, so the public figures are what the organization gave under its own name.
  • Guests could not follow their payment after checkout; the status token gives them the status without an account and without revealing anything about the payer to anyone who does not hold the token.
  • Security state is public, so embargoed findings are excluded from it entirely (ADR-0030), and from the public task list and the public digest page.

Notifications and webhooks

Notifications follow the same rules: private report notifications carry no content; embargoed findings notify only people entitled to see them; exception events, project review decisions and private reports are never sent to outbound webhooks or GitHub issues (crates/commonlayer-notifications/src/domain/catalog.rs).

Retention

  • In-app notifications are deleted after notifications.retention_days (default 180).
  • Expired and revoked sessions, consumed tokens and OAuth states are kept 30 days, then deleted by auth.cleanup.
  • Registry pull events are pruned after aggregation into daily statistics.
  • Audit and financial records are never deleted; they reference users by id.

A data-subject request process (export, deletion of personal data while keeping financial and audit records) is not implemented. The legal pages in the portal (/legal/privacy, /legal/terms) are templates; review by counsel is a decision for the operating entity.