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
*_publicthat 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_projectionsincrates/commonlayer-funding/tests/it/contributions.rs,http::public_routes_answer_anonymously_with_public_projectionsincrates/commonlayer-maintenance/tests/it/http.rs,projects::public_projection_contains_no_private_fieldsincrates/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
| Area | Public | Never public | Public type |
|---|---|---|---|
| Users | username, display name, avatar, bio, website, account kind, member since; approved public contributions | email, sessions, tokens, linked identities, private follows, notification settings | PublicUserResponse (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 contributions | members, invitations, internal notes, billing profile, service accounts; private organizations answer 404 | PublicOrganization (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 now | anything given anonymously (left out entirely, so the totals never reveal it), projects that are not public, payment references, the members who paid, the billing profile | OrganizationFundingPublic (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 confirmed | the 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 record | ContributionStatusPublic (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 dates | proposals in proposed, in_review or rejected state (404 to outsiders); the private section (manifest status, review notes) for holders of project.read_private | ProjectPublic (crates/commonlayer-projects/src/dto.rs) |
| Project funding | target, coverage, funding state, balance of each account kind, refundable balance, reserve runway, active and past allocation policies, campaigns | payment references, provider ids, fee details per payer | ProjectFundingPublic, 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 recurring | the name of anonymous contributors (also hidden from the organization and user attribution), emails, billing details, provider references, guest identities | PublicContribution (crates/commonlayer-funding/src/service/read.rs) |
| Project ledger | transaction kind, description, date, entries by account kind and amount | transaction metadata, the acting user | TransactionView without metadata and actor_type (crates/commonlayer-funding/src/service/ledger_admin.rs) |
| Monthly cycles | every cycle line: slot, payee username, planned and allocated amount, outcome (paid into obligations, held, forfeited, vacant, swept), destination, obligation status, explanation | payout destinations, tax status, bank details, the evaluation's private evidence | CycleLineView (crates/commonlayer-funding/src/service/cycles.rs) |
| Community rewards | recipient username, amount, rationale, status, approvals count, dates | approvers' private notes; the recipient's payout destination | RewardView (crates/commonlayer-funding/src/service/rewards.rs) |
| Infrastructure treasury | allocations and recorded expenses with category and description | vendor account details | InfrastructureReport (crates/commonlayer-funding/src/service/infrastructure.rs) |
| Maintainers | public bio and links, approval date, assignments (project, role, period), assignment history | payout destination, tax status, application notes, suspensions' reasons, agreements' acceptance IP | PublicMaintainerView, 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 private | evidence marked private, waiver reasons, assignees, finding references; security-acknowledgement tasks are left out entirely because their findings may be embargoed | PublicTaskView (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-256 | who accepted it and from where | AgreementText (crates/commonlayer-maintenance/src/service/listings.rs) |
| Eligibility | per period and active assignment: state, whether final, whether overridden, the rule summary, an explanation without private identifiers | stored inputs, evidence marked private, CVE identifiers of embargoed findings, appeals and their statements, override reasons | PublicEvaluationView (crates/commonlayer-maintenance/src/service/views.rs) |
| Security | findings on public projects once not embargoed, their timelines, exceptions with justification, VEX statements, advisories, scan history, digest vulnerabilities, public incidents | embargoed 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 incidents | crates/commonlayer-security/src/service/reads.rs |
| Artifacts | artifacts, 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 embargoed | crates/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 days | who pulled, client addresses, individual pull events | PullStats (crates/commonlayer-registry/src/service/pulls.rs) |
| Abuse reports | nothing | every report: visible to its reporter (GET /users/me/abuse-reports) and to platform administrators; the reported person or organization is not told who reported them | crates/commonlayer-organizations/src/service/abuse.rs |
| GitHub | pull requests tracked for public projects (not those of private repositories) | delivery payloads and logs | crates/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.