Skip to main content

Map and govern where your AI data and traffic flow — east-west / APAC lens.

Project description

borderlint

Map and govern where your AI data and traffic flow — east-west / APAC lens.

A static, in-CI check for HK / GBA entities: does your AI data stay within the jurisdictions your PDPO / PIPL policy allows? borderlint statically scans your repo (Python and TypeScript/JavaScript) for AI provider usage, resolves each flow to a jurisdiction (ccTLD codes plus the CN-GBA / GBA tokens), and fails the build on any flow outside the allow-list for the data class you declare. Western and Chinese providers are treated evenly. Zero runtime dependencies.

Use

python -m borderlint scan ./service --policy residency.json --classification customer-pii
  • No --policyinventory mode (lists flows + jurisdictions, exits 0).
  • --format json|mermaid|sarif|sbom — machine output, a flow map, SARIF for GitHub code-scanning, or a deterministic AI data-flow SBOM (policy-independent inventory of every flow; an artifact, exits 0).
  • diff <baseline.sbom> <current.sbom> — compare two SBOMs; exits 1 when the PR adds a new non-local flow (new egress), else 0. Diff the base-branch SBOM against the PR's to gate new AI egress.
  • Accept a reviewed flow with an inline # borderlint: allow <reason> waiver (justification required; it's reported as waived, not hidden, and can't override an explicit provider deny).
  • Exit code is non-zero on a violation, so it gates CI.

Policy (the eval-set)

residency.json maps each data class to the jurisdictions you accept:

{
  "home_location": "hk",
  "classifications": {
    "customer-pii": ["hk", "CN-GBA", "sg"],
    "employee-pii": ["hk", "CN-GBA"],
    "non-pii":      ["hk", "CN-GBA", "cn", "mo", "sg", "us", "gb"]
  }
}

Deny-by-default: a flow to any code not on the list for the declared class fails — so sg is allowed but my is not, matching a PDPO agreed-locations EULA. GBA is shorthand for hk + CN-GBA. Declare your home_location (hk, mo, or CN-GBA) and a flagged flow is tagged with the data-protection regimes in play (PDPO / Macao PDPA / PIPL) and the relevant cross-border arrangement — the matching GBA Standard Contract variant, (Mainland, Hong Kong) or (Mainland, Macao), PIPL cross-border, or GDPR SCCs — as reference links, never adjudicated. (home_regime pdpo/pipl is still accepted.)

Capabilities

  • Languages: Python (AST) and TypeScript/JavaScript (import / require / dynamic import()), plus endpoint references in config/text files and OpenAI-compatible /v1/chat/completions calls — even to a runtime-configured host (resolved to unknown, so on_unknown: fail gates it).
  • Providers: 13+ across the east-west boundary (OpenAI, Anthropic, Google, Azure, Bedrock, Mistral, Cohere + Tencent, Alibaba, DeepSeek, Moonshot, Zhipu, Baidu), with Python and JS/TS package names and the Vercel AI SDK (@ai-sdk/*).
  • Aggregators: litellm, langchain, LlamaIndex, aisuite, Vercel AI core (ai) → unknown (runtime-routed), so on_unknown: fail blocks them for sensitive classes.
  • Jurisdictions: ccTLD/ISO codes + CN-GBA / GBA; AWS/Azure region resolved from the endpoint host where present (e.g. bedrock-runtime.ap-east-1…hk).
  • Policy: classification-keyed JSON eval-set, deny-by-default, provider allow/deny, configurable failure set, declared home regime.
  • Regimes & arrangements: home location hk/mo/CN-GBA → PDPO / Macao PDPA / PIPL tags, linked to the matching GBA Standard Contract (HK or Macao), PIPL cross-border, or GDPR SCCs — reference only.
  • Output & CI: text / JSON / Mermaid / SARIF / SBOM, an SBOM diff gate for new egress, inline waivers, exit codes, GitHub Action + Jenkins.

Scope

For HK / GBA home bases under PDPO / PIPL / GBA. Not yet: vector-DB / storage residency, a pre-commit hook, CycloneDX / SPDX SBOM export, and optional LLM enrichment. Full roadmap in CAPABILITIES.md.

Internal endpoints

Map your own regional endpoints to jurisdictions; they merge with the bundled provider KB (your entries win on conflict):

{ "endpoints": { "llm-cn.acme.internal": "cn", "llm-hk.acme.internal": "hk", "llm-sg.acme.internal": "sg" } }
borderlint scan . --providers internal-endpoints.json --policy residency.json --classification customer-pii

A configuration wired to the wrong regional endpoint — e.g. the CN endpoint for HK/SG-only customer PII — then fails the build, so you can't ship a service pointed at the wrong region.

A runnable end-to-end example is in examples/gba-resident-app/ — a GBA-resident app (internal Shenzhen endpoint → CN-GBA, plus Mainland / Western / local fallbacks). Run it under residency-hk.json vs residency-mo.json and the surfaced GBA Standard Contract flips between the (Mainland, Hong Kong) and (Mainland, Macao) variant, and the regime tag between PDPO and Macao PDPA:

borderlint scan examples/gba-resident-app \
  --providers examples/gba-resident-app/internal-endpoints.json \
  --policy examples/gba-resident-app/residency-hk.json --classification customer-pii

CI

Same command in any pipeline. GitHub Actions (composite action):

- uses: iolairus/borderlint@v0.10.1
  with: { path: ., policy: residency.json, classification: customer-pii }

Jenkins / anything else: pip install borderlint && borderlint scan . --policy residency.json --classification customer-pii — a non-zero exit fails the stage. Full examples in examples/ci/.

Keeping the KB fresh

A weekly GitHub Action (.github/workflows/kb-refresh.yml) diffs the bundled provider KB against litellm's registry and opens an issue listing providers we don't yet cover — jurisdictions are assigned by hand, never auto-merged. borderlint --version shows the KB's last-reviewed date.

Development

borderlint is built spec-first with OpenSpec: every change is a reviewed proposal (specs + design + tasks) gated by a spec-reviewer agent before any code is written. To bootstrap the same workflow into another repo:

scripts/opsx-init.sh [--no-jira] /path/to/your/repo

It scaffolds AGENTS.md, .claude/ (slash commands + the spec-reviewer gate), an empty openspec/, and workflow.yaml. --no-jira trims it to the core loop — propose → review → apply → commit → ship.

License

MIT © 2026 Iolaire McKinnon. Vendor-neutral by design.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

borderlint-0.10.1.tar.gz (120.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

borderlint-0.10.1-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file borderlint-0.10.1.tar.gz.

File metadata

  • Download URL: borderlint-0.10.1.tar.gz
  • Upload date:
  • Size: 120.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for borderlint-0.10.1.tar.gz
Algorithm Hash digest
SHA256 623870922e0086407f6360cc5aa5beaa1f4d584a0484f0848f535526ea06e4da
MD5 ecc5866380e9ee4279d18e52baf76cfa
BLAKE2b-256 001127521df0b47fe2f7cfe0d9561e1bb9af211369e1e49ed094bf46af96b08d

See more details on using hashes here.

Provenance

The following attestation bundles were made for borderlint-0.10.1.tar.gz:

Publisher: release.yml on iolairus/borderlint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file borderlint-0.10.1-py3-none-any.whl.

File metadata

  • Download URL: borderlint-0.10.1-py3-none-any.whl
  • Upload date:
  • Size: 20.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for borderlint-0.10.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3c2809cca7b0f84a66e9c698e39099b7488382160bf77b5edfac84236ce032d5
MD5 8698f2ccde57f3218fc554c46a0758c7
BLAKE2b-256 c8782198c8219083a63de59700ed440450fdd277a934accebaaa38b027fb3a53

See more details on using hashes here.

Provenance

The following attestation bundles were made for borderlint-0.10.1-py3-none-any.whl:

Publisher: release.yml on iolairus/borderlint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page