← Tahr SecurityCONTENT HISTORY

Update to Tahr Security

Snapshot Sep 30, 2026 · 23:16 UTC · version 0.3.3

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "name": "tahr-test-access-control",
  "description": "Perform complete or focused, evidence-backed access-control review from source and optionally an explicitly authorized local or staging runtime. Model subjects, roles, tenants, resources, actions, properties, policy rules, enforcement points, and owner-attributed test cases; trace object-, function-, property-, role-, and tenant-level authorization through REST, GraphQL, web, job, and asynchronous paths; safely validate IDOR/BOLA/BFLA, mass assignment, privilege escalation, and cross-tenant isolation; and reject status-code or guessed-ID false positives. Use for authorization code review, multi-user or multi-tenant assessments, admin and role boundary analysis, pre-pentest review, or validation of a suspected access-control finding.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 320
    },
    {
      "relative_path": "assets/access-control-review.schema.json",
      "size_in_bytes": 58963
    },
    {
      "relative_path": "assets/access-control-review.template.json",
      "size_in_bytes": 84267
    },
    {
      "relative_path": "references/access-control-data-contract.md",
      "size_in_bytes": 22363
    },
    {
      "relative_path": "references/access-matrix.md",
      "size_in_bytes": 10579
    },
    {
      "relative_path": "references/access-proof-gates.md",
      "size_in_bytes": 18808
    },
    {
      "relative_path": "references/full-review-workflow.md",
      "size_in_bytes": 12557
    },
    {
      "relative_path": "references/runtime-test-safety.md",
      "size_in_bytes": 14252
    },
    {
      "relative_path": "references/source-review-patterns.md",
      "size_in_bytes": 11173
    },
    {
      "relative_path": "references/worked-example.md",
      "size_in_bytes": 17591
    },
    {
      "relative_path": "scripts/build_review_manifest.py",
      "size_in_bytes": 19653
    },
    {
      "relative_path": "scripts/render_access_control_review.py",
      "size_in_bytes": 47943
    },
    {
      "relative_path": "scripts/validate_access_control_review.py",
      "size_in_bytes": 114511
    }
  ],
  "skill_md_contents": "---\nname: tahr-test-access-control\ndescription: Perform complete or focused, evidence-backed access-control review from source and optionally an explicitly authorized local or staging runtime. Model subjects, roles, tenants, resources, actions, properties, policy rules, enforcement points, and owner-attributed test cases; trace object-, function-, property-, role-, and tenant-level authorization through REST, GraphQL, web, job, and asynchronous paths; safely validate IDOR/BOLA/BFLA, mass assignment, privilege escalation, and cross-tenant isolation; and reject status-code or guessed-ID false positives. Use for authorization code review, multi-user or multi-tenant assessments, admin and role boundary analysis, pre-pentest review, or validation of a suspected access-control finding.\n---\n\n# Tahr Test Access Control\n\nDetermine exactly who can perform which action on which resource, property, or\nfunction—and prove when the implementation violates that application-specific\nrule. Produce an authorization model and proof ledger, not a status-code diff.\n\n## Load the operating contract\n\nBefore reviewing:\n\n1. Read [full-review-workflow.md](references/full-review-workflow.md) for scope,\n   execution order, completion, and lifecycle rules.\n2. Read [access-control-data-contract.md](references/access-control-data-contract.md)\n   for stable IDs, exact enums, and record relationships.\n3. Read [access-matrix.md](references/access-matrix.md) before constructing\n   operation, relationship, carrier, property, or variant coverage.\n4. Read [access-proof-gates.md](references/access-proof-gates.md) before\n   accepting or rejecting a candidate.\n5. Read [runtime-test-safety.md](references/runtime-test-safety.md) before any\n   runtime action.\n6. Read [source-review-patterns.md](references/source-review-patterns.md) when\n   source is available.\n7. Use [worked-example.md](references/worked-example.md) only when the expected\n   evidence-to-finding trace is unclear.\n\nStart from [access-control-review.template.json](assets/access-control-review.template.json)\nand keep [access-control-review.schema.json](assets/access-control-review.schema.json)\nas the canonical output contract. Maintain one `access-control-review.json`;\nderive all reader-facing artifacts from it.\n\n## Choose scope and assurance honestly\n\nSet `review_mode` to:\n\n- `full` for every admitted authorization-relevant operation in the existing\n  application; or\n- `focused` for explicitly named operations, findings, resources, or policy\n  boundaries.\n\nDefault to `full` when the user asks to review or secure the application and\ndoes not explicitly narrow the authorization scope.\n\nSet `analysis_basis` to `source_only`, `runtime_only`, or `hybrid`. A focused\nreview must carry a visible limitation and must not make an application-wide\nclaim. A source-only review may be `complete` with `source_observed` assurance\nand planned runtime tests when every declared source surface is dispositioned.\nIt must not claim that an attack ran or that deployed enforcement failed.\n\nKeep these states separate:\n\n- `review_status`: whether the declared authorization scope was dispositioned;\n- `assurance_status`: source observation versus authorized runtime validation;\n- candidate `disposition`: lead, follow-up, rejected, source-confirmed, or\n  runtime-confirmed;\n- test `execution_status`: planned, passed, failed, inconclusive, or blocked;\n- coverage `status`: reviewed, tested, pending, deferred, or out of scope.\n\nDefault to read-only analysis. Never start an application, send a request,\nrefresh a session, or mutate state unless the exact target and action class are\nauthorized. Never commit, patch, or reconfigure the reviewed application as\npart of this skill.\n\n## Freeze the review inputs\n\nFor source or hybrid review, create a deterministic manifest in the selected\noutput directory:\n\n```bash\npython3 <skill-directory>/scripts/build_review_manifest.py \\\n  path/to/application --include . \\\n  --output path/to/output/repository-manifest.json\n```\n\nPass `--revision` for an immutable VCS or release revision. When omitted, the\nscript derives `snapshot-sha256:<digest>` from admitted paths and bytes. Copy\nits embedded revision and content hash into metadata, manifest evidence, and\ncoverage inventory. Repeat `--package` for package/module labels and\n`--document` for supplied repository policy or design files; documents are\nadmitted and hashed automatically. Use explicit empty arrays for absent\ndocuments or exclusions. When the output lives under the application root,\nplace it in a dedicated subdirectory such as `.tahr-review/`; the builder\nrecords and excludes that whole directory to prevent generated artifacts from\ncontaminating later snapshots, and refuses output directly in the root.\n\nInventory every admitted REST route, GraphQL query/mutation/subscription,\nserver action, RPC method, UI-backed function, webhook, worker/job, queue\nconsumer, export/download, bulk operation, legacy/versioned interface, and\nadministrative surface that makes or depends on an authorization decision.\nRecord intentionally public and non-applicable surfaces instead of deleting\nthem from the inventory.\n\nWhen `$tahr-map-attack-surface` is available, consume its frozen operation\ninventory and reconcile it; otherwise inventory locally. Companion skills are\noptional—the access-control skill must remain independently usable.\n\n## Establish identity and object truth\n\nModel unauthenticated, user, peer, role, tenant, administrator, support,\nservice, worker, integration, and other applicable subjects. Keep source-modeled\nidentities separate from runtime-verified sessions.\n\nFor runtime identities, bind the redacted auth artifact fingerprint to an\nobserved caller, role, tenant or authorization domain, transport, freshness,\nand validation evidence. A filename, configured label, JWT claim, profile\nfield, or successful HTTP response alone does not make a session trustworthy.\nMark unusable or mismatched identities as coverage limitations; never turn\ntheir failures into target-side denials.\n\nFor each target object, record resource type, exact identifier carrier, owner\nor controller, tenant/domain, sensitivity, lifecycle, and provenance. A shared\nID pool, guessed adjacent ID, globally discovered identifier, or caller-owned\n`/me` object cannot prove peer or cross-tenant impact. Use owner-attributed\nsource evidence, an authoritative owner baseline, or a disposable object\ncreated and read back under the owner identity.\n\nTreat supplied assessment identities as protected. Do not delete, disable,\nlock, re-role, rename, reset, or rotate them. Use fresh disposable objects and\nnon-protected accounts for state-changing validation.\n\n## Build the authorization model before judging\n\nRecord subject, action, resource, property, relationship, tenant/domain,\nworkflow state, feature/plan, authentication strength, and other policy\ncontext. Express each rule as `allow`, `deny`, `conditional`, or `unknown` and\ncite its authority.\n\nPrefer source policy, middleware, domain rules, role matrices, documented\nrequirements, or explicit assessment context. UI hiding, endpoint names,\ngeneric assumptions about administrators, and an owner-success baseline may\ncorroborate a rule but do not normally prove expected denial alone.\n\nFor every operation, enumerate each independent authorization obligation:\nsource object, destination object, parent, child, relationship object,\nproperty, function, and asynchronous continuation. Record every caller-supplied\nidentifier and sensitive property, where restrictions enter the path, where\nthey are consumed, the authoritative query or state change, and every\ndownstream enforcement point checked.\n\n## Trace controls end to end\n\nWhen source is available, trace shipped entrypoint to final data return,\nmutation, worker, integration, signed URL, audit record, notification, or other\nside effect. A route-level guard that permits an action somewhere is not proof\nthat the submitted target is in scope. A policy helper that exists but is not\nconsumed on this path is not a control.\n\nSearch for the strongest contradiction before retaining a gap: global\nmiddleware, dependency injection, decorators, domain policy, repository\nfilters, ORM scopes, serializers, workers, database policy, deployment\ncontrols, and sibling route variants. Mark dead, test-only, generated,\ndependency, or unreachable paths explicitly.\n\nGroup operations only when policy, resource, action, enforcement point, and\nrelevant carriers and variants genuinely match. Preserve operation-level IDs\nso grouping cannot hide a legacy route, bulk path, alternate parser, nested\nGraphQL resolver, or asynchronous continuation.\n\n## Construct complete matrix coverage\n\nFor each applicable operation, freeze the expected callers, relationships,\nidentifier/property carriers, and interface variants before recording results.\nInclude unauthenticated, own-object, same-role peer, cross-role, cross-tenant,\nservice-to-user, and privileged-function cases when the model makes them\nmeaningful.\n\nPair unauthorized cases with an authorized baseline of the same operation\nshape. Change one declared authorization dimension at a time. If an identity,\nowner-attributed object, parser, route variant, or safe fixture is unavailable,\nkeep the matrix cell and mark the exact blocker; never omit it to improve\ncoverage.\n\nRanking controls execution order, not inventory. A full review processes every\nexpected case or gives a specific disposition. Planned runtime validation does\nnot by itself make completed source coverage incomplete; missing high-risk\nsource analysis or an explicitly required runtime case does.\n\n## Execute only safe, discriminating tests\n\nFollow [runtime-test-safety.md](references/runtime-test-safety.md). Require the\ntest to match exactly one structured authorization target across origin,\nenvironment, surface/operation/resource IDs, tenant or domain, identities,\ntransport, action and mutation scope, request/attempt limits, and validity\nwindow. Use synthetic data and the smallest reversible proof.\n\nEvery test defines and distinguishes:\n\n- caller-identity proof;\n- owner/tenant/target attribution;\n- authorized baseline success;\n- expected denial or control-held signal;\n- unauthorized protected-data/action impact or control-failure signal;\n- authoritative readback and cleanup for state changes.\n\nAn executed result uses one `run_id`. Its freshly collected identity preflights\nand every observed signal must cite same-run, same-target runtime evidence.\nKeep purpose-specific evidence for each signal; one aggregate record cannot be\nthe sole proof for caller, target, baseline, denial/impact, readback, and\ncleanup. `planned` and `blocked` tests never contain a result.\n\nHTTP 200, non-empty output, size/hash differences, empty/null/false output,\ngeneric SPA shells, validation errors, 4xx/5xx reachability, 202 acceptance, or\nan echoed request are leads only. A mutation requires persistent authoritative\nreadback or an equivalent side effect. Repeat an accepted runtime failure with\nfresh identity state and a fresh authorized control.\n\n## Apply proof and false-positive gates\n\nUse the five mandatory gates: caller, target, ownership or tenant, expected\ndenial, and unauthorized impact. A source-confirmed candidate must connect a\nshipped reachable entrypoint to a concrete protected data/action sink, show the\nmissing or bypassed path-specific control, and record the strongest\ncontradiction checked. A runtime-confirmed candidate must additionally cite a\nconclusive authorized test result with direct runtime evidence.\n\nReject or retain as follow-up:\n\n- current-user endpoints returning only caller-owned or empty state;\n- legitimate sharing, public, support, or administrator behavior supported by\n  an applicable policy;\n- guessed or shared IDs without owner attribution;\n- wrong, stale, mismatched, or transport-incompatible identity material;\n- soft 404s, shells, parser errors, resource absence, or unproven server errors;\n- writes without readback, async acceptance without a side effect, or results\n  whose baseline changed more than the authorization dimension.\n\nRecord rejected leads with the applicable control or contradiction evidence.\nDo not erase them; they demonstrate that the review challenged its own leads.\n\n## Challenge and publish the model\n\nAfter the primary pass, use an independent subagent when available; otherwise\nperform a separate adversarial reasoning pass with fresh instructions. Require\nit to seek omitted operations and identities, unmodeled parent/child objects,\nunused restrictions, alternate routes/parsers/versions, false owner or tenant\nattribution, ambiguous collaboration, unsafe tests, unsupported impact, stale\nevidence, and hidden coverage gaps. Record every challenge and disposition.\n\nValidate the canonical model:\n\n```bash\npython3 <skill-directory>/scripts/validate_access_control_review.py \\\n  path/to/access-control-review.json --strict\n```\n\nFix failures, rerun the challenger when material content changes, and render:\n\n```bash\npython3 <skill-directory>/scripts/render_access_control_review.py \\\n  path/to/access-control-review.json --output-dir path/to/output --strict\n```\n\nThe renderer produces `access-control-review.md`, `validation-plan.json`,\n`findings.json`, and `coverage.json`. Do not edit derived artifacts as separate\nsources of truth.\n\nLead with confirmed source or runtime findings, unresolved high-risk\ncandidates, blocked tests, and coverage limitations. Never conclude that\naccess control or the application is secure. A clean result means only that no\nadditional proof-gated finding was produced within the declared completed\nscope and assurance level.\n"
}

SHA-256: 29024473d1eff6e1b2bbaeb49f0cc862e88e165da784335c953915734aec884e