1
0
Fork 0
llm-ingestion-pipeline-secu.../SECURITY.md
Kjell Tore Guttormsen 2b03b8d643 docs(security): add contact email, https scheme on Forgejo URL
Scorecard Security-Policy scored 4/10: no email address, bare
git.fromaitochitta.com URL without scheme. Both are worth 6 of 10 points
per Scorecard 5.5.0's model. Repo-specific policy text kept as-is.
2026-08-16 21:15:10 +02:00

3.9 KiB

Security policy

llm-ingestion-guard is a defensive library for LLM ingestion pipelines. Its own security posture matters: a flaw here can silently admit a poisoned artifact into a downstream corpus. Reports are welcome.

Supported versions

The project is 1.x. Only the latest published version receives fixes; there are no back-ported security branches. Pin a version and watch the CHANGELOG.md ### Security entries.

What 1.0.0 freezes, and what it does not. The freeze is a semver promise about the Python surface: no name exported from llm_ingestion_guard is removed, renamed or given a different meaning without a 2.0.0. It is not a promise that detection behaviour holds still. Severities, thresholds, lexicon entries and the dispositions they produce are calibration, and calibration moves in minor and patch releases — a payload that disposes WARN on 1.0.0 may dispose FAIL_SECURE on a later 1.x, and that is a fix rather than a break. Pin a version if you depend on a specific grading, and assert on the disposition your policy requires rather than on a severity you happened to observe.

Reporting a vulnerability

Do not open a public issue for a vulnerability. Public disclosure before a fix gives an attacker a window against every downstream consumer.

Instead, report it privately to security@fromaitochitta.com — mark the subject SECURITY.

Please include:

  • affected version / commit,
  • a minimal reproduction (input → observed disposition/finding vs. expected),
  • the impact you see (e.g. a poisoned artifact that disposes WARN instead of FAIL_SECURE).

Obfuscate any real payloads the same way the test corpus does — build attack strings from chr(0x…) fragments so the report itself does not ship a live carrier.

What counts as a vulnerability

In scope (a real finding):

  • a bypass of a stated control — e.g. an invisible carrier that reaches the persist gate without failing secure, a credential that egresses without a decoded:egress:* / egress:* label, a guard() path that fails open;
  • a prepare_input / screen_output code path that raises instead of failing closed;
  • a ReDoS or unbounded-resource input against the scanner.

Out of scope (documented boundaries — see the Known limitations section of README.md, not vulnerabilities):

  • semantic / factual poisoning invisible to lexicon + entropy;
  • a HIGH finding in trusted prose disposing to WARN (§4.7 trust-scaling);
  • hex-wrapped (non-base64) secret egress;
  • multimodal / binary-layer carriers (OCR, font stego, VBA/macros, encrypted files);
  • the multilingual homoglyph-mix false positive;
  • a low Severity on an ordinary outward fetch — on the detection side 1.x does not separate what was seen from how bad it is, so read the finding id for the capability;
  • the input-cap asymmetry at MAX_INPUT_CHARS: surfaces that return content raise OversizeInputError, surfaces that return findings truncate and emit active:oversize-input. Past the cap, "no finding" means "not looked at".

The last two are conceded for the whole of 1.x, deliberately and in writing (docs/LIMITATIONS.md): closing either changes an exported symbol's meaning and is therefore a 2.0.0 change. The homoglyph false positive is conceded differently — no fix is promised, but it is calibration, so one may land in any 1.x release.

If you are unsure whether something is in scope, report it privately anyway.

Disclosure

This is a small project without a formal embargo SLA. The maintainer will acknowledge a report, agree a fix + disclosure timeline with the reporter, and credit the reporter in the CHANGELOG.md ### Security entry unless they prefer to remain anonymous.