Security & data practices

Read-only by design. Never per-person by contract.

KalMatrix asks for read-only scopes, stores metadata — not your source code — and refuses to compute per-person analytics at the schema level. This page quotes the actual scope strings and the actual code, so you can hold us to it.

Ask us anything
Exactly what it can read

The scopes, verbatim.

These are the literal permission strings KalMatrix requests — copied from the OAuth configuration, not paraphrased. Neither grant contains a write scope, so KalMatrix cannot change a ticket, push a commit, or comment on a PR.

Jira — Atlassian OAuth 2.0 (3LO)

Read-only
read:jira-work read:jira-user offline_access
  • read:jira-work — issues, projects, sprints and their history. That's the whole board read.
  • read:jira-user — display names, to match the same person across Jira and GitHub.
  • offline_access — the refresh token, so syncs keep running without re-consent.
  • No write: scope of any kind is in the grant — Atlassian enforces that, not just us.

GitHub — GitHub App

Read-only
Pull requests: Read-onlyContents: Read-onlyMetadata: Read-only
  • Installed as a GitHub App with read-only repository permissions — you pick exactly which repos at install time, and can revoke per-repo any time from GitHub.
  • Optionally, Copilot Business (organization): Read-only — only if you want AI-adoption charts from GitHub's own org metrics.
  • Every other permission is "No access". The app cannot write, merge, comment, or trigger anything.
What actually lands in the database

Metadata in. Source code never.

The sync requests lists of pull requests, reviews, commits and changed filenames — it never requests file contents or diffs. What it stores is the delivery skeleton, capped and truncated on purpose.

Stored
  • PR metadata: title, description (truncated to 2,000 characters), state, timestamps, line counts, and up to 100 changed filenames.
  • Review events and comment counts — who reviewed, when, how much. Used for review-latency and bottleneck math.
  • Commit messages (truncated to 500 characters), including Co-authored-by trailers — that's how AI-assisted work is attributed.
  • Jira issues, sprints, story points, and status history — the board as it already is.
  • Contributor names, logins and commit emails — only to recognize the same engineer across both tools.
Never collected
  • Source code contents or diffs. The sync fetches file lists, never file bodies or patches — there is no code path that requests them.
  • Per-person AI usage. Enforced at the schema level, not by policy — see the contract below.
  • Anything from laptops. No IDE plugin, no browser extension, no agent, no keystrokes. KalMatrix reads two APIs: Jira and GitHub.
  • Small-group analytics. Team-level numbers are only computed for teams at or above the aggregation floor — 5 people by default, configurable per org.
The never-per-person guarantee

It's a comment in our schema, not a paragraph in our policy.

Measurement tools drift into surveillance one dashboard at a time. KalMatrix draws the line in the data model: AI-usage metrics are aggregated to the team before they are stored, so a per-person leaderboard isn't a setting we've turned off — it's data that doesn't exist.

  • Team aggregates only, and only for teams of 5+ (the org-configurable aggregation floor). Below the floor, the analytics are skipped, not blurred.
  • Where a name does appear — a pending reviewer to ping — it's routing, capped and omitted when identity resolution is poor. Never a ranking.
  • AI agents get scoreboards. Humans never do — agents aren't people.
server/src/models/core.js — verbatim
/* ------------------------------------------------ */
/* Identity — one engineer in the customer org,      */
/* across tools.                                     */
/* The privacy contract: AI usage is NEVER stored    */
/* per-identity.                                     */
/* ------------------------------------------------ */

Self-hosters can read this file — and every claim on this page — in the source they run.

Credentials

Encrypted where stored. Not stored where possible.

AES-256-GCM at rest

Jira OAuth tokens are encrypted with AES-256-GCM (authenticated encryption, random IV per record) before they touch the database. The key lives in an environment variable on your deployment, never in the database.

GitHub: no stored token at all

The GitHub App holds no long-lived credential. Short-lived installation tokens are minted on demand from the app’s private key and expire on their own — there is nothing durable to leak.

Passwords & audit trail

User passwords are bcrypt-hashed, sessions are signed JWTs, and connect/disconnect and admin actions are written to an audit log.

Deletion

Your data, deleted on request.

Email us and we delete your organization's data — issues, PR metadata, forecasts, history, the lot. Revoking the integrations on the provider side (Atlassian admin, GitHub App settings) cuts off access instantly and independently of us. No export ransom, no retention theater.

Request deletion
Self-host

Or keep the data in your walls.

The entire stack — API, worker, web client, MongoDB — ships as a docker-compose you run on your own infrastructure. Same code, same read-only scopes, and nothing ever leaves your network. If your client contracts say the data can't sit on a vendor's cloud, this is the answer.

See plans & self-host

Trust is a scope string you can check.

Read a delivery brief on demo data right now, or send us the security questionnaire — we like the questions this page answers.

Contact us

Read-only scopes · AES-256-GCM at rest · Never per-person · Patented forecasting method (Indian patent)