Skip to content

Account product listing is not subject-scoped: owners see only public products #215

Description

@alukach

Summary

aws s3 ls s3://{account}/ returns only public products, even when the caller owns the account. Unlisted and restricted products are invisible to their own owner.

Cause

SourceCoopRegistry::list_products passes None as the subject, so the product-list call is the only Source API lookup that is not subject-scoped — it goes out with no Authorization header:

https://github.com/source-cooperative/data.source.coop/blob/main/src/source_api/registry.rs#L29-L38

pub async fn list_products(&self, account: &str) -> Result<Vec<String>, ProxyError> {
    let product_list = super::cache::get_or_fetch_product_list(
        &self.api_base_url,
        account,
        &self.api_auth,
        &self.request_id,
        None,          // <-- subject
    )

With subject: None, cached_fetch skips the Authorization header and cache_key_with_subject returns the bare URL, so all callers share one cache entry.

Downstream, GET /api/v1/products/{account_id} filters on Actions.ListRepository, which returns true for an anonymous caller only when visibility === "public". Hence the owner sees the anonymous view of their own account.

Structural obstacle

AccountListHandler is a RouteHandler, and route handlers run before identity resolution in the multistore pipeline — so there is no resolved subject available at the point list_products is called. Fixing this likely means either resolving identity earlier for this route, or moving account listing off the route-handler path.

Impact

  • Fails safe — over-restrictive, no data leak.
  • But listing is a primary discovery path, and an owner cannot see their own non-public products through the S3 API.
  • The shared, unsubjected cache entry is also inconsistent with the subject-scoped keying used by every other lookup.

Notes

Found while auditing the ADRs in #115 against the implementation. ADR-005 and ADR-007 currently claim all lookups are subject-scoped; that text is being corrected separately.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions