Data and security

Getting your data out

Any backlog can be downloaded as a complete, loss-free copy from inside the app at any time — items, sub-items, notes, tags and the full history of who changed what. The file is plain, documented JSON with a tamper-evident signature, and it can be restored back into the app.

An organisation can pull all of its content programmatically, on a schedule, authenticated by its own corporate directory. There is no API key to create or look after: access is granted and revoked in your directory, alongside your joiners-and-leavers process.

A nightly export, ready to schedule
#!/bin/sh
# Nightly: pull everything out into a dated file that you keep.
# The token comes from YOUR directory (client credentials); the service
# issues no API key and stores no credential for this.
# set -eu and the -f/-e flags make any failure — bad credentials, an
# outage, no token — stop the script with an error, so it can never
# write something that merely looks like a backup.
set -eu
TOKEN=$(curl -fsS -X POST \
  "https://login.microsoftonline.com/<your-directory-id>/oauth2/v2.0/token" \
  -d grant_type=client_credentials \
  -d client_id="<your-automation-app-id>" \
  -d client_secret="$AUTOMATION_SECRET" \
  -d scope="api://<sign-in-client-id>/.default" | jq -re .access_token)

curl -fsS -H "Authorization: Bearer $TOKEN" \
  "https://<this-site>/api/tenant/export?tenant=<your-company-id>" \
  -o "backlog-export-$(date +%Y-%m-%d).obk.json"
Converting an export into spreadsheets
// node export-to-csv.mjs backlog-export-2026-01-31.obk.json
// Turns an export into one .csv per backlog — readable in Excel or
// anything else, with no software of ours involved.
import { readFileSync, writeFileSync } from 'node:fs';

const file = JSON.parse(readFileSync(process.argv[2], 'utf8'));
// A cell that starts like a formula gets a leading apostrophe, so a
// spreadsheet shows it as text rather than evaluating it.
const cell = (v) => {
  const s = String(v ?? '');
  return '"' + (/^[=+@-]/.test(s) ? "'" + s : s).replaceAll('"', '""') + '"';
};
let n = 0;
for (const backlog of file.payload.backlogs) {
  const rows = [['Ref', 'Parent', 'Description', 'Status', 'Size', 'Tags', 'Notes']];
  const walk = (items, parent) => {
    for (const item of items ?? []) {
      rows.push([
        item.ref ?? item.id, parent, item.description, item.status,
        item.size ?? '', (item.tags ?? []).join(' '),
        (item.notes ?? []).map((note) => note.text).join(' | '),
      ]);
      walk(item.children, item.ref ?? item.id);
    }
  };
  walk(backlog.items, '');
  const name = backlog.name.replace(/[^A-Za-z0-9 _-]/g, '').trim() || 'backlog';
  n += 1; // numbered: two backlogs may share a name, and nothing may overwrite
  writeFileSync(n + ' ' + name + '.csv', rows.map((r) => r.map(cell).join(',')).join('\n'));
}

The second script uses no software of ours, so a copy you have downloaded stays readable whatever happens to this service.

Administrators find the same export as a button, with the exact commands for their own directory, on the company page.

Automated review of the code

Every release is reviewed automatically by a language model that is not part of the team writing the code, and the result is published here with the date it ran, the change it covers, and the exact instructions the reviewer was given. The review re-runs on each deployment, so an old date means the running code has not changed since. What is published is deliberately coarse — an assessment per area, the outcome of each check on a fixed list drawn from the OWASP Top Ten, and counts of open findings by severity — and carries no code, file names or other internals.

The instructions the reviewer is given

For each area: You are an independent security reviewer producing a PUBLIC assessment of one area of a codebase for prospective customers. You did not write this code and owe its authors nothing: be fair, not kind — report what the code actually shows, neither softened nor inflated, and credit protections that are genuinely present. You assess the area against a fixed checklist drawn from the OWASP Top Ten, and every finding names its check: "access-control" — authorisation that is missing or bypassable, or data crossing organisation boundaries; "crypto" — weak or misused cryptography, secrets handled or stored badly; "injection" — injection of any kind, including cross-site scripting; "config" — insecure defaults, headers or deployment configuration; "components" — vulnerable, outdated or unnecessary dependencies; "auth" — flaws in sign-in, session handling or credential lifecycle; "integrity" — unverified updates, unsafe deserialisation, or supply-chain weakness in the pipeline; "logging" — security events that would go unrecorded or unnoticed; "ssrf" — requests the server can be tricked into making; "other" — any real problem outside these categories, stability included. Weigh every finding by risk — how likely it is to be exploited and what happens if it is. "critical" means attackers could plausibly compromise data or accounts today; "high" means a serious weakness to fix promptly; "medium" means a real weakness of limited impact or needing unusual circumstances; "low" means a worthwhile hardening. Do not inflate a theoretical concern to signal diligence, and do not omit a problem because the rest of the area is good. You answer with STRICT JSON only, of the shape {"confidence":"high"|"medium"|"low","note":string,"findings":[{"severity":"critical"|"high"|"medium"|"low","check":string,"note":string}]}, where "check" is one of the checklist ids above. "confidence" is how confident a customer should feel about this area. Each note is plain prose for a non-technical reader, at most 350 characters. Because the assessment is public, notes must NEVER contain code, secrets, file names, paths, URLs, function or variable names, or step-by-step exploit detail. List at most 5 findings, only for problems that matter; style preferences are not findings. An empty findings list is a valid answer.

For the overall verdict: You are an independent security reviewer summarising a completed review for prospective customers. Answer with STRICT JSON only: {"verdict":string} — one plain-prose paragraph, at most 700 characters, honest about weaknesses, no code, names, paths or URLs.

Reviewed 3 August 2026, 08:06 UTC (today) · change c5a994c · 96 files · model @cf/meta/llama-4-scout-17b-16e-instruct

Every area is assessed against a fixed checklist drawn from the OWASP Top Ten. What was checked, and how many findings each check left open:

Checked forCriticalHighMediumLow
Broken access control0001
Cryptographic failures0002
Injection and cross-site scripting0000
Security misconfiguration0062
Vulnerable or outdated components0038
Authentication and session failures0043
Software and data integrity failures0010
Security logging and monitoring failures00011
Server-side request forgery0002
Other risks0001

The reviewed system demonstrates a robust security posture, with several areas showing well-structured and secure implementations. However, some medium and low-severity findings were identified, including concerns with session expiration, logging mechanisms, and potential configuration issues. Additionally, some dependencies and libraries may require updates or more thorough security assessments. Overall, the system's security is strong, but attention to these findings is recommended to further enhance its security and resilience.

Open findings for the team to look at: 0 critical, 0 high, 14 medium, 30 low.

What is built in

The overview at Security covers the same ground in the terms a security reviewer will ask about.

All policies · Sign in