How your organisation’s data is protected
Leagues hold real information about real people, a lot of them minors. This page describes what BallOBall actually implements — and, just as plainly, what it does not claim. No certification badges, because there are no certifications.
What BallOBall does not claim
- No compliance certification
- No SOC 2, ISO 27001, PCI DSS or HIPAA attestation, and no certification under GDPR, FERPA or COPPA. No third party has audited this platform.
- No uptime SLA
- There is no published availability commitment, and no measured uptime figure to quote.
- No enterprise identity federation
- No SAML, no OIDC federation, no SCIM directory sync.
- No customer-managed encryption keys
- Encryption uses managed AWS defaults; there is no bring-your-own-key or HSM option.
If any of these is a hard requirement for your organisation, say so before you commit — we would rather lose the deal than have you discover it in month three.
The controls actually in place
Everything below is built and running today. Unbadged items are included on every plan; a badge means the capability needs a module added to your plan, a higher plan tier, or a piece of setup finished first.
Keeping organisations apart
The question every multi-tenant platform has to answer: what stops one organisation seeing another’s data? Here it is enforced by the database, not by remembering to add a filter.
Multi-tenant data isolation enforced in the database (Postgres RLS)
Every database query runs through a Prisma extension that switches the connection to a non-owner Postgres role and sets a per-request tenant identifier, so PostgreSQL row-level security policies — not just application code — decide which organization's rows a request can see.
The API stack defaults RLS_ENFORCEMENT to 'strict', but it is a deploy-time context flag, and the Auth stack deliberately runs it 'off' for Cognito triggers. A signed-in user with no organization (a fan) is mapped to the public scope, which runs as the BYPASSRLS role: such a caller has no tenant rows to be confined to, so what limits those reads is each handler's own WHERE clause — the caller's own user id, or an explicit resource id — rather than RLS. The case RLS exists for, an authenticated member of one organization reading another, still requires a tenant and stays fully enforced.
Role-based access control with scoped grants
BallOBall ships a fixed set of roles — platform admin, platform support, league admin, coach, scorekeeper, referee, player, fan and a scan-only gate agent — and league admins can grant additional roles to members, including grants scoped to a single sport, league or team.
Roles are a fixed enum; organizations cannot define their own top-level roles. Sensitive listings (minors' ID documents, referee 1099 earnings, background-check results) require an organization-wide grant, because narrower club-scoped grants intentionally pass the coarse role check used for navigation gates — those endpoints call a separate tenant-wide guard that rejects a club-, league-, team- or sport-scoped grant.
Custom staff roles with capabilities, at club level
Within a club, admins can create named roles with a chosen set of capabilities and assign members to them, and those capabilities gate club surfaces such as the club reports.
Custom roles exist only at the club level, not at the organization or league level, and they draw from a fixed capability list rather than arbitrary permissions.
Signing in
Accounts run on Amazon Cognito. Email verification is required, and two-factor authentication is available to any user without asking an administrator.
Email and password sign-in on Amazon Cognito, with email verification required
Accounts are managed in Amazon Cognito, and new sign-ups must confirm their email address before the account is usable unless an operator explicitly enables auto-confirm.
Auto-confirm is a deploy flag that defaults to false; enabling it would skip verification. Cognito treats the email as a case-sensitive username.
Self-serve two-factor authentication (authenticator app / TOTP)
Any signed-in user can turn on two-factor authentication with a standard authenticator app from their own security settings, and turn it off again.
TOTP only — no SMS and no hardware-key second factor. The user pool has MFA set to OPTIONAL, so 2FA is opt-in per user unless a platform operator turns on the platform-wide requirement. Enrollment is presented via a copyable secret and otpauth:// URI, not a rendered QR code — no QR library is a dependency, so the secret is typed or pasted into the authenticator app.
Platform-wide security policy: session timeout, IP allowlist, mandatory 2FA
A saved security policy — maximum session age, an IP allowlist, and a requirement that all users enroll a second factor — is enforced by the API on every authenticated request.
This is a single platform-wide policy stored on one settings row and editable only by BallOBall platform staff (SUPER_ADMIN / PLATFORM_SUPPORT). Customer organizations cannot set their own session timeout, IP allowlist, or 2FA requirement. Of the three 2FA scopes, only ALL_USERS is enforced at the API — ROOT_ONLY and ALL_PLATFORM_ADMINS name exactly the two platform roles that bypass every check in this middleware, deliberately, so those two settings are saved but unenforced.
Data protection and recovery
Storage-level encryption and automated backups on managed AWS infrastructure, plus rate limiting to blunt abuse.
Encryption at rest, automated backups and deletion protection
The production database is encrypted at rest with automated backups and deletion protection enabled, and uploaded files live in a versioned, encrypted bucket with all public access blocked.
AWS-managed encryption keys (S3-managed for objects, default RDS storage encryption) — there is no bring-your-own-key or customer-managed KMS option. Backup retention is configured at seven days. Everything runs in a single AWS region (us-east-2 by default), so there is no data-residency choice.
Abuse protection: per-tenant and per-IP rate limiting
Every API request passes through a rate limiter that counts requests per organization and per client IP in a fixed one-minute window and returns a throttling response once the budget is exceeded.
A single shared default budget applies per organization-and-IP pair; it is not configurable per customer. A named set of hot scoring routes is explicitly exempted.
Audit trail of administrative actions
Administrative actions across the platform write audit records capturing the action, the actor, the target and a timestamp, browsable and filterable in a paginated console with a per-organization view.
Both the platform-wide and per-organization audit feeds are readable only by BallOBall platform staff (SUPER_ADMIN / PLATFORM_SUPPORT); there is no audit-log screen a customer's own admin can open. Writes are best-effort and fire after the mutation commits — if the audit insert fails it is logged to CloudWatch and the mutation still stands, so the trail is not a transactional guarantee.
People’s rights over their data
Members and guardians can get their data out or have it erased, and sensitive member records live in a permissioned vault rather than in email threads.
Data-subject rights: account deletion, data export and erasure
A user can delete their own account from within the app, and a minor's data can be exported or erased by the player, a verified guardian, an organization admin or platform staff — deliberately not behind any feature toggle.
Self-deletion is refused for staff accounts and for anyone who still owns an organization; ownership must be transferred first. Whole-organization export and user anonymization are platform-staff actions, not self-serve.
Secure document vault for household and member records
Families and organization admins can store residency, medical, insurance and photo-ID documents against a household: the storage key is generated server-side and bound to the uploader with a signed token, the file is never given a public URL, and retrieval happens only through a short-lived signed link.
Access is limited to a guardian of that household, an admin of the household's organization, and platform staff. The underlying bucket uses S3-managed encryption with public access blocked; there is no customer-managed key option.
Guardian links and minor-messaging policy
Guardians can be linked to and verified against a minor player, team messaging is checked against that policy before a message is stored, and admins get a review queue of policy violations they can resolve.
The policy currently LOGS violations rather than blocking them — the service's stated v1 contract always returns allowed, so no message is actually refused, and no notification is sent to the guardian when a violation fires. Hard-blocking is described in the code as v2 work behind a per-tenant flag that does not exist yet.
The questions procurement asks
Are you SOC 2 or ISO 27001 certified?
No. BallOBall holds no compliance certification or third-party attestation of any kind — not SOC 2, not ISO 27001, not PCI DSS, not HIPAA, and no certification under GDPR, FERPA or COPPA. Anyone telling you otherwise is wrong. What this page describes is the architecture and the controls that are actually implemented.
How is our data kept separate from another organisation’s?
By row-level security in Postgres. Every tenant-scoped query is filtered at the database layer against the current organisation, so a missing filter in application code cannot expose another organisation’s rows — the database refuses rather than the application remembering.
Do you store card numbers?
No. Card details are never handled by BallOBall’s own code; payment flows are hosted by the payment provider. That is a consequence of the architecture, not a compliance certification — see the first answer.
Can we enforce SSO against our identity provider?
Not today. There is no SAML or OIDC federation, and no SCIM directory sync. Sign-in is email and password on Cognito, with optional Google and Apple sign-in, plus self-serve two-factor authentication. If enterprise identity federation is a requirement for you, tell us — but do not plan around it existing now.
Is there an API we can integrate with?
Not a public one. API keys can be generated in an internal admin screen, but no request is authenticated by an API key today and no outbound webhooks are emitted, so there is nothing to build against yet.
What happens to our data if we leave?
Organisation data can be exported, and account deletion and erasure requests are supported. Export and purge at organisation scale are run by the platform team rather than self-serve from your own settings screen.
Our data processing agreement and privacy policy set out the contractual side.
Got a security question we have not answered?
Ask it before you sign, not after. We will tell you plainly if the answer is no.