Files
archy/scripts/tailscale-security.py

74 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Offline Tailworm packaging floor check; never installs or contacts a daemon.
Version evidence is supplied explicitly. Passing is only a version-floor result,
not package provenance, running-daemon, configuration, or fleet acceptance.
"""
import argparse
import json
from pathlib import Path
import re
MINIMUM = (1, 104, 4)
BULLETINS = [f"TS-2026-{n:03d}" for n in range(14, 18)]
def release_version(value):
# Only stable upstream releases and numeric Debian packaging revisions.
# Do not turn rc/dev/dirty builds or unknown vendor backports into passes.
match = re.fullmatch(r"v?(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-[1-9][0-9]*)?", value)
if not match:
return None
version = tuple(map(int, match.groups()))
if version[0] != 1 or version[1] % 2:
return None
return version
def assess(value):
version = release_version(value)
return {
"version": value,
"status": "unknown-version" if version is None else (
"meets-security-floor" if version >= MINIMUM else "below-security-floor"
),
}
def check_manifest(path):
import yaml
app = yaml.safe_load(Path(path).read_text())["app"]
if app["id"] != "tailscale":
raise ValueError("expected tailscale app")
version = str(app["version"])
result = assess(version)
image = app["container"]["image"]
# Require a reviewable exact release tag; digest may additionally pin it.
match = re.fullmatch(r"[^\s@]+:v(1\.[0-9]+\.[0-9]+)(?:@sha256:[0-9a-f]{64})?", image)
if not match or match[1] != version:
result["status"] = "unversioned-or-mismatched-image"
result.update(manifest=str(path), image=image)
return result
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--version", action="append", default=[], help="explicit package/binary version; repeat for CLI and daemon")
parser.add_argument("--manifest", type=Path)
args = parser.parse_args()
if not args.version and args.manifest is None:
parser.error("supply --version and/or --manifest")
results = [assess(value) for value in args.version]
if args.manifest is not None:
try:
results.append(check_manifest(args.manifest))
except (OSError, ValueError, KeyError, TypeError, ImportError) as error:
results.append({"status": "manifest-error", "error": str(error)})
print(json.dumps({"scope": "version-floor-only", "minimum": "1.104.4", "bulletins": BULLETINS, "results": results}, indent=2))
return 0 if all(row["status"] == "meets-security-floor" for row in results) else 1
if __name__ == "__main__":
raise SystemExit(main())