Security and data governance

This page describes what the platform does today: how data is classed, who can grant and end access to it, what gets logged, and who can read it. It does not describe anything planned.

The three data classes

Every table the platform owns falls into exactly one of three classes, and no table straddles two:

  • Athlete-owned: the training log and daily check-ins. This data follows the athlete, not the team.
  • Club-owned: the roster, weekly plans, channels, and race entries. This data belongs to the team.
  • Platform-operational: authentication, sessions, delivery records, and audit rows. This data belongs to neither an athlete nor a team; it exists to run the platform itself.

Grants

A team reads and writes an athlete's training data through a grant: a scoped, revocable record naming which team can see which person's data, and at what access level. Today, a grant ends when the holding team relinquishes it or when it expires; a new grant starts fresh.

An invite, a relinquishment, and every token change write an audit row naming the actor, the grant or token, and the reason. An expired grant stops granting access at read time and leaves no audit row of its own. Every authorization denial writes an audit row too: a caller with too low a tier, a caller reaching for a scope it does not hold, or a caller reaching for a person that does not exist. A rate-limited request and an invalid or revoked token are also denied, but neither writes an audit row. Roster and admin actions are audit-logged as well. Training-log and check-in writes made through the API are not logged today, and neither are successful reads. That is a limit of the current system.

Tokens

A team's API access rides a bearer token, one of two kinds by its prefix, and a team operator mints either kind at /team/tokens. An xca_live_ token is a real integration credential; a team holds at most two live tokens at once. An xca_test_ token has no such cap. It reaches the team's real data with the same access as a live token of the same tier. Revoking a token takes effect immediately; a revoked token's calls answer 401 from that point on.

Published rate limits

Every rate limit the API enforces, its window, its threshold, and what happens when a caller exceeds it, is published as data: Rate limits (JSON).

Operator access

Geoff Wright operates this platform and can read the data it stores, across every team. The platform runs on Cloudflare, in the United States.

Minors

Most athletes on the platform are minors. An athlete's data is entered under a team that athlete's own coach operates; there is no way to join without a coach adding the athlete to a roster. A question about what is stored, or a request to remove it, goes through that team's coach, or through the contact form.

Retention and deletion

Archiving a roster member never deletes their person record or their training history; it marks the membership archived, which removes the coach's visibility into it entirely, past history included, since only a non-archived membership can be seen at all.

A deletion request, passed along by a coach or made through the contact form, removes the training log, check-ins, notification settings, and any phone registered for push notifications. Roster and team records a club needs to keep, such as who was on the team and when, are kept separately and are not touched by that request. Full detail on what is kept and who can see it lives on the privacy page.

Breach notification

There is no formal breach-notification program. If the operator becomes aware of unauthorized access to a team's data, the operator notifies that team's coaches directly.

Vulnerability reporting

There is no dedicated security-reporting channel. Report a vulnerability through the contact form.

Last reviewed: August 25, 2026.