{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "WEB013", "name": "robots.txt does not declare any User-agent rules", "shortDescription": {"text": "robots.txt does not declare any User-agent rules"}, "fullDescription": {"text": "Add at least `User-agent: *` and explicit Allow/Disallow rules."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "medium", "confidence": 0.83, "cwe": "", "owasp": ""}}, {"id": "WEB003", "name": "Public web service has no security.txt", "shortDescription": {"text": "Public web service has no security.txt"}, "fullDescription": {"text": "Add /.well-known/security.txt with Contact, Expires, Canonical, Preferred-Languages, and Policy fields. Keep the contact endpoint monitored."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "medium", "confidence": 0.78, "cwe": "", "owasp": ""}}, {"id": "AUC009", "name": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function", "shortDescription": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /su"}, "fullDescription": {"text": "Require an explicit admin, maintainer, super_admin, or scoped service role in code and .repobility/access.yml."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.68, "cwe": "", "owasp": ""}}, {"id": "AUC004", "name": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence ", "shortDescription": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /invoices."}, "fullDescription": {"text": "Define whether this endpoint is admin-only or super_admin-only, then enforce that distinction in code and .repobility/access.yml."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.66, "cwe": "", "owasp": ""}}, {"id": "AUC002", "name": "[AUC002] Low visible authorization coverage in route inventory: Only 11.7% of discovered routes show nearby authenticati", "shortDescription": {"text": "[AUC002] Low visible authorization coverage in route inventory: Only 11.7% of discovered routes show nearby authentication, authorization, middleware, or public-route evidence."}, "fullDescription": {"text": "Review the access matrix and add explicit framework auth declarations or policy-file exceptions for intentionally public routes."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.74, "cwe": "", "owasp": ""}}, {"id": "AUC001", "name": "[AUC001] No Repobility access matrix policy found: The repository uses web/API frameworks but does not define .repobilit", "shortDescription": {"text": "[AUC001] No Repobility access matrix policy found: The repository uses web/API frameworks but does not define .repobility/access.yml or equivalent authorization documentation."}, "fullDescription": {"text": "Add .repobility/access.yml mapping routes to anonymous, authenticated, owner, admin, and super_admin. Keep business-specific rules in the repo so CI can enforce them."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.92, "cwe": "", "owasp": ""}}, {"id": "DKR001", "name": "Docker final stage has no non-root USER", "shortDescription": {"text": "Docker final stage has no non-root USER"}, "fullDescription": {"text": "Add a non-root USER in the final runtime stage after files and permissions are prepared."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.82, "cwe": "", "owasp": ""}}, {"id": "DKR014", "name": "Dockerfile copies broad context with incomplete .dockerignore", "shortDescription": {"text": "Dockerfile copies broad context with incomplete .dockerignore"}, "fullDescription": {"text": "Tighten .dockerignore or replace COPY . with explicit COPY statements."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.76, "cwe": "", "owasp": ""}}, {"id": "DKR004", "name": "Docker build secret exposed through ARG", "shortDescription": {"text": "Docker build secret exposed through ARG"}, "fullDescription": {"text": "Replace secret ARG usage with `RUN --mount=type=secret,id=name ...` and pass the value with `docker build --secret`."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.62, "cwe": "", "owasp": ""}}, {"id": "DKR009", "name": "Dockerfile separates apt update from install", "shortDescription": {"text": "Dockerfile separates apt update from install"}, "fullDescription": {"text": "Combine update and install in the same RUN instruction and clean package indexes in that layer."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.86, "cwe": "", "owasp": ""}}, {"id": "SEC015", "name": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable.", "shortDescription": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "fullDescription": {"text": "Use secrets module (Python) or crypto.getRandomValues() (JS) for security-sensitive randomness."}, "properties": {"scanner": "repobility-threat-engine", "category": "crypto", "severity": "medium", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC001", "name": "[SEC001] Hardcoded Password: Hardcoded password found in source code.", "shortDescription": {"text": "[SEC001] Hardcoded Password: Hardcoded password found in source code."}, "fullDescription": {"text": "Use environment variables or a secrets manager."}, "properties": {"scanner": "repobility-threat-engine", "category": "credential_exposure", "severity": "medium", "confidence": 0.3, "cwe": "", "owasp": ""}}, {"id": "WEB005", "name": "robots.txt does not advertise a sitemap", "shortDescription": {"text": "robots.txt does not advertise a sitemap"}, "fullDescription": {"text": "Add `Sitemap: https://your-domain.example/sitemap.xml` to robots.txt."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.74, "cwe": "", "owasp": ""}}, {"id": "AUC005", "name": "[AUC005] No authorization-focused tests detected: No test files with common authorization, ownership, 403, admin, or sup", "shortDescription": {"text": "[AUC005] No authorization-focused tests detected: No test files with common authorization, ownership, 403, admin, or super_admin assertions were found."}, "fullDescription": {"text": "Add regression tests for anonymous denial, cross-user object denial, admin role limits, and super_admin-only behavior."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "low", "confidence": 0.76, "cwe": "", "owasp": ""}}, {"id": "DKR011", "name": "Dockerfile installs recommended OS packages", "shortDescription": {"text": "Dockerfile installs recommended OS packages"}, "fullDescription": {"text": "Add `--no-install-recommends` and explicitly list only packages the image needs."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "DKR010", "name": "Dockerfile leaves apt package indexes in the image layer", "shortDescription": {"text": "Dockerfile leaves apt package indexes in the image layer"}, "fullDescription": {"text": "End the apt install layer with `rm -rf /var/lib/apt/lists/*`."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.74, "cwe": "", "owasp": ""}}, {"id": "DKR008", "name": ".dockerignore misses sensitive defaults", "shortDescription": {"text": ".dockerignore misses sensitive defaults"}, "fullDescription": {"text": "Add missing patterns such as .env, .git, private keys, certificates, dependency folders, and local databases."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "AIC003", "name": "Duplicated implementation block across source files", "shortDescription": {"text": "Duplicated implementation block across source files"}, "fullDescription": {"text": "Extract the shared behavior into one function/module or delete the inactive duplicate after proving which path is used."}, "properties": {"scanner": "repobility-ai-code-hygiene", "category": "quality", "severity": "low", "confidence": 0.86, "cwe": "", "owasp": ""}}, {"id": "DKR002", "name": "Dockerfile base image is selected through a build variable", "shortDescription": {"text": "Dockerfile base image is selected through a build variable"}, "fullDescription": {"text": "Resolve the variable to a versioned tag or digest in production builds and document the allowed images."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "info", "confidence": 0.48, "cwe": "", "owasp": ""}}, {"id": "MINED043", "name": "[MINED043] Http Not Https: Hardcoded http:// (not localhost) for endpoints that handle credentials or data.", "shortDescription": {"text": "[MINED043] Http Not Https: Hardcoded http:// (not localhost) for endpoints that handle credentials or data."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-319 / A02:2021 for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC096", "name": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql (and 1 more): Same pattern found in 1 additional files.", "shortDescription": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql (and 1 more): Same pattern found in 1 additional files. Review if needed."}, "fullDescription": {"text": "Use parameterized form: `.where(\"name = ?\", user_input)` or named placeholders."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 0.2, "cwe": "", "owasp": ""}}, {"id": "SEC128", "name": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake) (and 11 more): Same pattern found in 11 add", "shortDescription": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake) (and 11 more): Same pattern found in 11 additional files. Review if needed."}, "fullDescription": {"text": "Add `await` before each async call, or chain with `.then`. If you intentionally want fire-and-forget, prefix with `void` (TS) or assign to `_` (Python with `asyncio.create_task`) to make the intent explicit and survive lint."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 0.2, "cwe": "", "owasp": ""}}, {"id": "SEC029", "name": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 13 more): Same pattern found in 13 addi", "shortDescription": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 13 more): Same pattern found in 13 additional files. Review if needed."}, "fullDescription": {"text": "Validate the URL against an allowlist BEFORE fetching:\n  ALLOWED = {'images.example.com', 'cdn.example.com'}\n  host = urlparse(url).hostname\n  if host not in ALLOWED: abort(400)\nOr use a server-side proxy (Imgproxy / serve-files-only-from-S3) that isolates outbound network access from the request handler.\nBlock private CIDRs explicitly: 10/8, 172.16/12, 192.168/16, 169.254/16."}, "properties": {"scanner": "repobility-threat-engine", "category": "ssrf", "severity": "info", "confidence": 0.2, "cwe": "", "owasp": ""}}, {"id": "SEC020", "name": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequen", "shortDescription": {"text": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequent AI-assisted coding failure: the helper exposes the exact value needed for troubleshooting."}, "fullDescription": {"text": "Log only redacted, hashed, or last-four-style metadata. Rotate any secret that may have reached logs."}, "properties": {"scanner": "repobility-threat-engine", "category": "credential_exposure", "severity": "info", "confidence": 0.15, "cwe": "", "owasp": ""}}, {"id": "MINED091", "name": "[MINED091] Ruby Rescue Bare: rescue without exception class catches StandardError too broadly.", "shortDescription": {"text": "[MINED091] Ruby Rescue Bare: rescue without exception class catches StandardError too broadly."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-755 /  for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "MINED115", "name": "[MINED115] Action `aws-actions/amazon-ecr-login` pinned to mutable ref `@v2`: `uses: aws-actions/amazon-ecr-login@v2` re", "shortDescription": {"text": "[MINED115] Action `aws-actions/amazon-ecr-login` pinned to mutable ref `@v2`: `uses: aws-actions/amazon-ecr-login@v2` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-fi"}, "fullDescription": {"text": "Replace with: `uses: aws-actions/amazon-ecr-login@<40-char-sha>  # v2` and let Dependabot bump it on a scheduled cadence."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "MINED126", "name": "[MINED126] Workflow container/services image `getlago/postgres-partman:15.0-alpine` unpinned: `container/services image:", "shortDescription": {"text": "[MINED126] Workflow container/services image `getlago/postgres-partman:15.0-alpine` unpinned: `container/services image: getlago/postgres-partman:15.0-alpine` without `@sha256:...` pulls a mutable tag at workflow-run time. Treat workflow co"}, "fullDescription": {"text": "Replace with `getlago/postgres-partman:15.0-alpine@sha256:<digest>`. Re-pin via Dependabot Docker scope."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "MINED118", "name": "[MINED118] Dockerfile FROM `ruby:4.0.2-slim` not pinned by digest: `FROM ruby:4.0.2-slim` resolves the tag at build time", "shortDescription": {"text": "[MINED118] Dockerfile FROM `ruby:4.0.2-slim` not pinned by digest: `FROM ruby:4.0.2-slim` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production image"}, "fullDescription": {"text": "Replace with: `FROM ruby:4.0.2-slim@sha256:<digest>`. Get the digest from `docker manifest inspect`. Re-pin via a scheduled bot (Renovate, Dependabot)."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "AUC003", "name": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby a", "shortDescription": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /payment_receipts/:id."}, "fullDescription": {"text": "Add ownership, tenant, relationship, or policy checks before reading or mutating the target object."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "high", "confidence": 0.7, "cwe": "", "owasp": ""}}, {"id": "DKR006", "name": "Dockerfile pipes a remote script into a shell", "shortDescription": {"text": "Dockerfile pipes a remote script into a shell"}, "fullDescription": {"text": "Download the artifact, verify its checksum or signature, pin the version, and then execute it."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "high", "confidence": 0.92, "cwe": "", "owasp": ""}}, {"id": "SEC120", "name": "[SEC120] Hardcoded HMAC key or JWT signing secret: JWT/HMAC signing secret hardcoded in source. Anyone with source acces", "shortDescription": {"text": "[SEC120] Hardcoded HMAC key or JWT signing secret: JWT/HMAC signing secret hardcoded in source. Anyone with source access can forge tokens; secret leaks via git history."}, "fullDescription": {"text": "Load from environment variable or secret manager: `process.env.JWT_SECRET`, `os.environ['JWT_SECRET']`. Generate with `openssl rand -base64 64`. Rotate."}, "properties": {"scanner": "repobility-threat-engine", "category": "credential_exposure", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "CORE_NO_TESTS", "name": "No test files found", "shortDescription": {"text": "No test files found"}, "fullDescription": {"text": "Add a test directory (tests/ or __tests__/) with unit tests for core functionality. Use pytest (Python), Jest (JS/TS), or go test (Go). Start with tests for critical business logic and security-sensitive functions."}, "properties": {"scanner": "repobility-core", "category": "testing", "severity": "high", "confidence": null, "cwe": "", "owasp": ""}}, {"id": "MINED116", "name": "[MINED116] Workflow uses `secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` on a `pull_request` trigger: This workflow trigge", "shortDescription": {"text": "[MINED116] Workflow uses `secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }` l"}, "fullDescription": {"text": "Either remove the secret reference, or switch the trigger to `pull_request_target` AND ensure no fork-controlled code runs before the secret is consumed."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "critical", "confidence": 0.9, "cwe": "", "owasp": ""}}]}}, "automationDetails": {"id": "repobility/974"}, "properties": {"repository": "getlago/lago-api", "repoUrl": "https://github.com/getlago/lago-api", "branch": "main"}, "results": [{"ruleId": "WEB013", "level": "warning", "message": {"text": "robots.txt does not declare any User-agent rules"}, "properties": {"repobilityId": 91414, "scanner": "repobility-web-presence", "fingerprint": "c254a6b0468b4dd98b2c1d738ce943c09943d33023bc4395e67a0ada41a2c778", "category": "quality", "severity": "medium", "confidence": 0.83, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Discovered robots file or route lacks a User-agent directive.", "evidence": {"rule_id": "WEB013", "scanner": "repobility-web-presence", "references": ["https://www.rfc-editor.org/rfc/rfc9309"], "correlation_key": "fp|c254a6b0468b4dd98b2c1d738ce943c09943d33023bc4395e67a0ada41a2c778"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/robots.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB003", "level": "warning", "message": {"text": "Public web service has no security.txt"}, "properties": {"repobilityId": 91413, "scanner": "repobility-web-presence", "fingerprint": "5cd26606c5a53c9f403ff7a92a6917c19cf440a23ce03e2b90e8c493312ef8cd", "category": "quality", "severity": "medium", "confidence": 0.78, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app/API but no security.txt file or route was discovered.", "evidence": {"rule_id": "WEB003", "scanner": "repobility-web-presence", "references": ["https://www.rfc-editor.org/rfc/rfc9116", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|5cd26606c5a53c9f403ff7a92a6917c19cf440a23ce03e2b90e8c493312ef8cd"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".well-known/security.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /subscriptions."}, "properties": {"repobilityId": 91411, "scanner": "repobility-access-control", "fingerprint": "ed9a8076c424c747426693fb5bfb3d5106bd9f96e32b06229d32ec19ca912101", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/subscriptions", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|61|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 61}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /payment_requests."}, "properties": {"repobilityId": 91410, "scanner": "repobility-access-control", "fingerprint": "24b9e4be07d7219ea46920b3df3d778a405297cead9a63e00112890d697da267", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/payment_requests", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|60|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 60}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /payments."}, "properties": {"repobilityId": 91409, "scanner": "repobility-access-control", "fingerprint": "a63afe5848bd9badba581492fc17aabb7e24ea5bddfe4876ff9193f3faf869ce", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/payments", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|59|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 59}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /invoices."}, "properties": {"repobilityId": 91408, "scanner": "repobility-access-control", "fingerprint": "a21d00dc0b371437ab12479bb96c92c15551fe4b41c56eb74c1b0928e2b2c078", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/invoices", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|58|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 58}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /credit_notes."}, "properties": {"repobilityId": 91407, "scanner": "repobility-access-control", "fingerprint": "815a37a791a193e716899e0867d4b3daaf194328ad1e58f0b2ded7e4b0b83067", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/credit_notes", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|57|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 57}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /applied_coupons."}, "properties": {"repobilityId": 91406, "scanner": "repobility-access-control", "fingerprint": "bd04d42214aa63eee26a5f58969257a166549dd5eaa079e13a2a9ea10b59fbf5", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/applied_coupons", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|56|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 56}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /customers."}, "properties": {"repobilityId": 91405, "scanner": "repobility-access-control", "fingerprint": "6fb1e69ad4994dbf9f5f617767e9c99bb94d12fbe3d6a362ad127f1c30947970", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/customers", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|46|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 46}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /billing_entities."}, "properties": {"repobilityId": 91404, "scanner": "repobility-access-control", "fingerprint": "6e9d0a563f21636a364104192a0b207d07efdcf216fc7257c65ccf9f87fda504", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/billing_entities", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|44|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 44}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /analytics/usage."}, "properties": {"repobilityId": 91403, "scanner": "repobility-access-control", "fingerprint": "06553428cad3e170d767e210a45a91d49d5c30c71edb204466073dc9bf8d021f", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/analytics/usage", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|42|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 42}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: ANY /graphql."}, "properties": {"repobilityId": 91402, "scanner": "repobility-access-control", "fingerprint": "e1819383423b71fcff06cf55f25c428baae6ac29200802d92d483165ec138e90", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/graphql", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|13|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 13}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /invoices."}, "properties": {"repobilityId": 91401, "scanner": "repobility-access-control", "fingerprint": "f3ac758c4683cc52302133c82aa2be60379891511767b88a64fc9d6916848208", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/invoices", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|209|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 209}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /organizations."}, "properties": {"repobilityId": 91400, "scanner": "repobility-access-control", "fingerprint": "fed11f05358b4a670dddc70dac0625fff19e39c2371a4152ea6fa8873274aad4", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/organizations", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|208|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 208}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /memberships."}, "properties": {"repobilityId": 91399, "scanner": "repobility-access-control", "fingerprint": "ef26ea6ba34c350ca28c94d9f6978ccc1929d86ab32edf364df446fc9574b8d3", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/memberships", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|207|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 207}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /moneyhash/:organization_id."}, "properties": {"repobilityId": 91398, "scanner": "repobility-access-control", "fingerprint": "8b9861402d9e3a4c2c13e6d07e65156deab99974bc797f711d39c28f549188f8", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/moneyhash/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|203|auc004", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 203}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /adyen/:organization_id."}, "properties": {"repobilityId": 91397, "scanner": "repobility-access-control", "fingerprint": "b7f1052736196ee2d111a40e1c3d3ec4c0041751d6798e54e25464461ef9130a", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/adyen/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|202|auc004", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 202}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /gocardless/:organization_id."}, "properties": {"repobilityId": 91396, "scanner": "repobility-access-control", "fingerprint": "716d9ed276fc040056d1dab9c07424bab01f52078b5920dd480fe7585fa93249", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/gocardless/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|201|auc004", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 201}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /flutterwave/:organization_id."}, "properties": {"repobilityId": 91395, "scanner": "repobility-access-control", "fingerprint": "e180f0f5c4c3c902b5c02391824045cc9372b72f7df4368111382141a37d801e", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/flutterwave/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|200|auc004", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 200}}}]}, {"ruleId": "AUC002", "level": "warning", "message": {"text": "[AUC002] Low visible authorization coverage in route inventory: Only 11.7% of discovered routes show nearby authentication, authorization, middleware, or public-route evidence."}, "properties": {"repobilityId": 91384, "scanner": "repobility-access-control", "fingerprint": "947b1f07d394ea7a04a102848b6570e63d9305a110da25722f10050cf68808e8", "category": "auth", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"scanner": "repobility-access-control", "endpoint_count": 77, "correlation_key": "fp|947b1f07d394ea7a04a102848b6570e63d9305a110da25722f10050cf68808e8", "auth_visible_percent": 11.7}}}, {"ruleId": "AUC001", "level": "warning", "message": {"text": "[AUC001] No Repobility access matrix policy found: The repository uses web/API frameworks but does not define .repobility/access.yml or equivalent authorization documentation."}, "properties": {"repobilityId": 91383, "scanner": "repobility-access-control", "fingerprint": "f1305052c3ba1e6c1cdb5dccc19e58a8168cf78b176658f32b1fc823df3e9d10", "category": "auth", "severity": "medium", "confidence": 0.92, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"scanner": "repobility-access-control", "frameworks": ["Rails"], "expected_files": [".repobility/access.yml", ".repobility/access.yaml", ".repobility/access.json", ".repobility/authorization.yml"], "correlation_key": "fp|f1305052c3ba1e6c1cdb5dccc19e58a8168cf78b176658f32b1fc823df3e9d10"}}}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 91382, "scanner": "repobility-docker", "fingerprint": "0d5ff3d41ee0d717c64b642ba699427420a77f8d003ffc4acd65300ecbbf3dc5", "category": "docker", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "No USER directive was found in the final runtime stage.", "evidence": {"rule_id": "DKR001", "scanner": "repobility-docker", "final_base": "ruby:4.0.2-slim", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|0d5ff3d41ee0d717c64b642ba699427420a77f8d003ffc4acd65300ecbbf3dc5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile.dev"}, "region": {"startLine": 10}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 91376, "scanner": "repobility-docker", "fingerprint": "fd1a36829bfcc153393f56643ede68ab8d0139402573706dba145cc978e14382", "category": "docker", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "No USER directive was found in the final runtime stage.", "evidence": {"rule_id": "DKR001", "scanner": "repobility-docker", "final_base": "ruby:4.0.2-slim", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|fd1a36829bfcc153393f56643ede68ab8d0139402573706dba145cc978e14382"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 33}}}]}, {"ruleId": "DKR014", "level": "warning", "message": {"text": "Dockerfile copies broad context with incomplete .dockerignore"}, "properties": {"repobilityId": 91375, "scanner": "repobility-docker", "fingerprint": "ccb5c1a80fd5cc0f3011d050ec6fcc752cb6feb15420dae7fc95a0c2b565e03c", "category": "docker", "severity": "medium", "confidence": 0.76, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Broad context copy found and .dockerignore misses sensitive defaults.", "evidence": {"rule_id": "DKR014", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|ccb5c1a80fd5cc0f3011d050ec6fcc752cb6feb15420dae7fc95a0c2b565e03c", "missing_patterns": [".env", "id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 54}}}]}, {"ruleId": "DKR004", "level": "warning", "message": {"text": "Docker build secret exposed through ARG"}, "properties": {"repobilityId": 91374, "scanner": "repobility-docker", "fingerprint": "9e5b0a7602c9fcb65b7e08c24236fdaf315f28cc9cd656a40354eb7cd3293782", "category": "docker", "severity": "medium", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "ARG name looks secret-bearing; BuildKit secret mounts are the safer pattern.", "evidence": {"rule_id": "DKR004", "scanner": "repobility-docker", "variable": "GOCARDLESS_CLIENT_SECRET", "references": ["https://docs.docker.com/build/building/secrets/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|9e5b0a7602c9fcb65b7e08c24236fdaf315f28cc9cd656a40354eb7cd3293782"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 42}}}]}, {"ruleId": "DKR009", "level": "warning", "message": {"text": "Dockerfile separates apt update from install"}, "properties": {"repobilityId": 91372, "scanner": "repobility-docker", "fingerprint": "49823ad70246d527ae140a3d431e414b8ea9b63f59475f0807f0c086ad0d58d5", "category": "docker", "severity": "medium", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Package index update appears without package installation in the same layer.", "evidence": {"rule_id": "DKR009", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|49823ad70246d527ae140a3d431e414b8ea9b63f59475f0807f0c086ad0d58d5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 37}}}]}, {"ruleId": "DKR009", "level": "warning", "message": {"text": "Dockerfile separates apt update from install"}, "properties": {"repobilityId": 91369, "scanner": "repobility-docker", "fingerprint": "a445628df964a57fe8c56a7f40e216827de166f4cb6256761431f9c66232f708", "category": "docker", "severity": "medium", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Package index update appears without package installation in the same layer.", "evidence": {"rule_id": "DKR009", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|a445628df964a57fe8c56a7f40e216827de166f4cb6256761431f9c66232f708"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 16}}}]}, {"ruleId": "SEC015", "level": "warning", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 91349, "scanner": "repobility-threat-engine", "fingerprint": "930f4af744a726c5e396fc69260a48758df5038a09949c531639a9a22cf5b971", "category": "crypto", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "evidence": {"match": "def generate_token", "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|crypto|token|42|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/services/auth/okta/login_service.rb"}, "region": {"startLine": 42}}}]}, {"ruleId": "SEC015", "level": "warning", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 91348, "scanner": "repobility-threat-engine", "fingerprint": "cdf45699cf8c88656c7076fd2258b48d7e0143006b4708446bac08bd29486ea2", "category": "crypto", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "evidence": {"match": "def generate_token", "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|crypto|token|91|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/services/auth/google_service.rb"}, "region": {"startLine": 91}}}]}, {"ruleId": "SEC015", "level": "warning", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 91347, "scanner": "repobility-threat-engine", "fingerprint": "1865efc6676fcf4df09d29577e5ad5d55321b481bdcfee2b91b9ca74e3a8c267", "category": "crypto", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "evidence": {"match": "def generate_webhook_secret", "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|crypto|token|30|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/payment_providers/flutterwave_provider.rb"}, "region": {"startLine": 30}}}]}, {"ruleId": "SEC001", "level": "warning", "message": {"text": "[SEC001] Hardcoded Password: Hardcoded password found in source code."}, "properties": {"repobilityId": 91346, "scanner": "repobility-threat-engine", "fingerprint": "f1119abb8a6dc3d9f66157a7cd6e6bef56f1ce434bcb3d753498ed2a4a3e5ba1", "category": "credential_exposure", "severity": "medium", "confidence": 0.3, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Low entropy value (3.5 bits) \u2014 may be placeholder or common string", "evidence": {"match": "PASSWORD = \"<redacted>\"", "reason": "Low entropy value (3.5 bits) \u2014 may be placeholder or common string", "rule_id": "SEC001", "scanner": "repobility-threat-engine", "confidence": 0.3, "correlation_key": "secret|token|1|password redacted"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/concerns/organizations/authentication_methods.rb"}, "region": {"startLine": 7}}}]}, {"ruleId": "WEB005", "level": "note", "message": {"text": "robots.txt does not advertise a sitemap"}, "properties": {"repobilityId": 91415, "scanner": "repobility-web-presence", "fingerprint": "12d1aab6ee1a443feb14574bf5d0fbdb1f0693f388e4ba974e05b2dfd78786e8", "category": "quality", "severity": "low", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Discovered robots file or route lacks a Sitemap directive.", "evidence": {"rule_id": "WEB005", "scanner": "repobility-web-presence", "references": ["https://www.rfc-editor.org/rfc/rfc9309", "https://www.sitemaps.org/protocol.html"], "correlation_key": "fp|12d1aab6ee1a443feb14574bf5d0fbdb1f0693f388e4ba974e05b2dfd78786e8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/robots.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "AUC005", "level": "note", "message": {"text": "[AUC005] No authorization-focused tests detected: No test files with common authorization, ownership, 403, admin, or super_admin assertions were found."}, "properties": {"repobilityId": 91412, "scanner": "repobility-access-control", "fingerprint": "c58bb88e6682225dc480b3036f30153044953a3d94f500396678a77324e8d30e", "category": "auth", "severity": "low", "confidence": 0.76, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"scanner": "repobility-access-control", "frameworks": ["Rails"], "correlation_key": "fp|c58bb88e6682225dc480b3036f30153044953a3d94f500396678a77324e8d30e"}}}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 91381, "scanner": "repobility-docker", "fingerprint": "4343e815c76443edaf5293919cd443d2765b55bf37c613302fe1b9acbec8a279", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|4343e815c76443edaf5293919cd443d2765b55bf37c613302fe1b9acbec8a279"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile.dev"}, "region": {"startLine": 15}}}]}, {"ruleId": "DKR010", "level": "note", "message": {"text": "Dockerfile leaves apt package indexes in the image layer"}, "properties": {"repobilityId": 91380, "scanner": "repobility-docker", "fingerprint": "c14f8a9ddf51fb415d3a69c0cc4a65030c851f9cc3f3b30e991cc46ef00d4f93", "category": "docker", "severity": "low", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt update/install layer does not remove /var/lib/apt/lists.", "evidence": {"rule_id": "DKR010", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|c14f8a9ddf51fb415d3a69c0cc4a65030c851f9cc3f3b30e991cc46ef00d4f93"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile.dev"}, "region": {"startLine": 15}}}]}, {"ruleId": "DKR008", "level": "note", "message": {"text": ".dockerignore misses sensitive defaults"}, "properties": {"repobilityId": 91377, "scanner": "repobility-docker", "fingerprint": "aea2ad92c68c4ee1f8432bb1ec25e7d45ac12c9e1790ac2d3fffe638b1acce12", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "A Docker build context should exclude secrets and repository metadata.", "evidence": {"rule_id": "DKR008", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|aea2ad92c68c4ee1f8432bb1ec25e7d45ac12c9e1790ac2d3fffe638b1acce12", "missing_patterns": [".env", "id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".dockerignore"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 91373, "scanner": "repobility-docker", "fingerprint": "e622e166b746e79026fef23536591815984f91c5090d33e356afe375bd8f273c", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|e622e166b746e79026fef23536591815984f91c5090d33e356afe375bd8f273c"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 38}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 91371, "scanner": "repobility-docker", "fingerprint": "6156a9e38005fa1db7bf224d6d6039922f0a7289ced82774e7446cc165b9e687", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|6156a9e38005fa1db7bf224d6d6039922f0a7289ced82774e7446cc165b9e687"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 17}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91367, "scanner": "repobility-ai-code-hygiene", "fingerprint": "6315688b30708b880459c4b381d9ecc1e44e32d5b44c23715e54e09cd537449f", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/graphql/mutations/subscriptions/destroy_charge_filter.rb", "duplicate_line": 19, "correlation_key": "fp|6315688b30708b880459c4b381d9ecc1e44e32d5b44c23715e54e09cd537449f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/graphql/mutations/subscriptions/update_charge_filter.rb"}, "region": {"startLine": 22}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91366, "scanner": "repobility-ai-code-hygiene", "fingerprint": "32a53fe19c668b9d55bb6c4792d94dbf8d6edb38c1f6b83d0d8c82ddfd14fe91", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/graphql/mutations/plans/create.rb", "duplicate_line": 17, "correlation_key": "fp|32a53fe19c668b9d55bb6c4792d94dbf8d6edb38c1f6b83d0d8c82ddfd14fe91"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/graphql/mutations/plans/update.rb"}, "region": {"startLine": 17}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91365, "scanner": "repobility-ai-code-hygiene", "fingerprint": "911706c533600d5dae72d13b31a8a4c2fa375bc1a1031034547bdec60e58ac70", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/graphql/mutations/data_exports/credit_notes/create.rb", "duplicate_line": 11, "correlation_key": "fp|911706c533600d5dae72d13b31a8a4c2fa375bc1a1031034547bdec60e58ac70"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/graphql/mutations/data_exports/invoices/create.rb"}, "region": {"startLine": 11}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91364, "scanner": "repobility-ai-code-hygiene", "fingerprint": "72d38fd0c0de60b093850391cf1d13e4334d6cdba9a61bb9a9976c1061bc4b75", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/customers/wallets/metadata_controller.rb", "duplicate_line": 4, "correlation_key": "fp|72d38fd0c0de60b093850391cf1d13e4334d6cdba9a61bb9a9976c1061bc4b75"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/wallets/metadata_controller.rb"}, "region": {"startLine": 3}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91363, "scanner": "repobility-ai-code-hygiene", "fingerprint": "ccca267449108605821b696c8ee35dfa3d36731933dd799df69f13887463c2be", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/plans/fixed_charges_controller.rb", "duplicate_line": 9, "correlation_key": "fp|ccca267449108605821b696c8ee35dfa3d36731933dd799df69f13887463c2be"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/subscriptions/fixed_charges_controller.rb"}, "region": {"startLine": 8}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91362, "scanner": "repobility-ai-code-hygiene", "fingerprint": "3372ca2bbdb8d97a158b59d1adca7b3f330f9baf16e1003405ba235e625a2a10", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/subscriptions/base_controller.rb", "duplicate_line": 8, "correlation_key": "fp|3372ca2bbdb8d97a158b59d1adca7b3f330f9baf16e1003405ba235e625a2a10"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/subscriptions/entitlements_controller.rb"}, "region": {"startLine": 55}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91361, "scanner": "repobility-ai-code-hygiene", "fingerprint": "dabd2c1e2275b00057e47ed2c491b4f46abadd63f458a61d75ed6806c3c5deff", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/subscriptions/entitlements/privileges_controller.rb", "duplicate_line": 12, "correlation_key": "fp|dabd2c1e2275b00057e47ed2c491b4f46abadd63f458a61d75ed6806c3c5deff"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/subscriptions/entitlements_controller.rb"}, "region": {"startLine": 20}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91360, "scanner": "repobility-ai-code-hygiene", "fingerprint": "9c6c9b12a399aced6d561bd7223c3e038203d3436219203e53c68b2f5bef8ed6", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/subscriptions/base_controller.rb", "duplicate_line": 8, "correlation_key": "fp|9c6c9b12a399aced6d561bd7223c3e038203d3436219203e53c68b2f5bef8ed6"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/subscriptions/entitlements/privileges_controller.rb"}, "region": {"startLine": 30}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91359, "scanner": "repobility-ai-code-hygiene", "fingerprint": "7b41a129cb1d1b615c645258ac30f96b6d5fc55d7b1a1bd6ddd7a5615613617f", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/plans/charges_controller.rb", "duplicate_line": 9, "correlation_key": "fp|7b41a129cb1d1b615c645258ac30f96b6d5fc55d7b1a1bd6ddd7a5615613617f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/subscriptions/charges_controller.rb"}, "region": {"startLine": 8}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91358, "scanner": "repobility-ai-code-hygiene", "fingerprint": "4ded184e524da4527d38dd137275e35d8fdb148afe882ffe9d6a0a4df1ea6753", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/plans/charges/filters_controller.rb", "duplicate_line": 6, "correlation_key": "fp|4ded184e524da4527d38dd137275e35d8fdb148afe882ffe9d6a0a4df1ea6753"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/subscriptions/charges/filters_controller.rb"}, "region": {"startLine": 6}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91357, "scanner": "repobility-ai-code-hygiene", "fingerprint": "0e1e4a5b973ea4b9f9fda3d3289d100b6b40ff33989ad8c232bf4d3f44abc662", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/customers/wallets/alerts_controller.rb", "duplicate_line": 22, "correlation_key": "fp|0e1e4a5b973ea4b9f9fda3d3289d100b6b40ff33989ad8c232bf4d3f44abc662"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/subscriptions/alerts_controller.rb"}, "region": {"startLine": 31}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91356, "scanner": "repobility-ai-code-hygiene", "fingerprint": "4924f59d89dbb426627ce938eae509074898704785707994f9e2001b9dea92b5", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/plans/entitlements/privileges_controller.rb", "duplicate_line": 13, "correlation_key": "fp|4924f59d89dbb426627ce938eae509074898704785707994f9e2001b9dea92b5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/plans/entitlements_controller.rb"}, "region": {"startLine": 66}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91355, "scanner": "repobility-ai-code-hygiene", "fingerprint": "41b83e1129ad2161448573f8b7344389d6128bedfc32cc1e8116f2a5736b3e93", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/analytics/gross_revenues_controller.rb", "duplicate_line": 7, "correlation_key": "fp|41b83e1129ad2161448573f8b7344389d6128bedfc32cc1e8116f2a5736b3e93"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/analytics/overdue_balances_controller.rb"}, "region": {"startLine": 7}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91354, "scanner": "repobility-ai-code-hygiene", "fingerprint": "aa8f934c72ca0f98361042a3c4d62ac3dc0a8b05e8de3c4b04d049164e0acd04", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/analytics/invoice_collections_controller.rb", "duplicate_line": 7, "correlation_key": "fp|aa8f934c72ca0f98361042a3c4d62ac3dc0a8b05e8de3c4b04d049164e0acd04"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/analytics/mrrs_controller.rb"}, "region": {"startLine": 7}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 91353, "scanner": "repobility-ai-code-hygiene", "fingerprint": "93954fab7df2972b249dd17024b2293b8e4f707fc12dfdf4aacb84aa1c41853f", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "app/controllers/api/v1/analytics/invoice_collections_controller.rb", "duplicate_line": 7, "correlation_key": "fp|93954fab7df2972b249dd17024b2293b8e4f707fc12dfdf4aacb84aa1c41853f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/analytics/invoiced_usages_controller.rb"}, "region": {"startLine": 7}}}]}, {"ruleId": "DKR002", "level": "none", "message": {"text": "Dockerfile base image is selected through a build variable"}, "properties": {"repobilityId": 91378, "scanner": "repobility-docker", "fingerprint": "758ffecc994e81c9f5936111515db467fc3306ed2cf337f701dee48ff549dce8", "category": "docker", "severity": "info", "confidence": 0.48, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Base image contains a variable; manual review is needed to avoid false positives.", "evidence": {"image": "golang:${GO_VERSION}", "rule_id": "DKR002", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://docs.docker.com/scout/policy/"], "correlation_key": "fp|758ffecc994e81c9f5936111515db467fc3306ed2cf337f701dee48ff549dce8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile.dev"}, "region": {"startLine": 4}}}]}, {"ruleId": "DKR002", "level": "none", "message": {"text": "Dockerfile base image is selected through a build variable"}, "properties": {"repobilityId": 91368, "scanner": "repobility-docker", "fingerprint": "3d5114dccd29cff75883e418b3f13e42df10ee33eef795c33f27d73d19bbb355", "category": "docker", "severity": "info", "confidence": 0.48, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Base image contains a variable; manual review is needed to avoid false positives.", "evidence": {"image": "golang:${GO_VERSION}", "rule_id": "DKR002", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://docs.docker.com/scout/policy/"], "correlation_key": "fp|3d5114dccd29cff75883e418b3f13e42df10ee33eef795c33f27d73d19bbb355"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 4}}}]}, {"ruleId": "MINED043", "level": "none", "message": {"text": "[MINED043] Http Not Https: Hardcoded http:// (not localhost) for endpoints that handle credentials or data."}, "properties": {"repobilityId": 91352, "scanner": "repobility-threat-engine", "fingerprint": "7953f2a6af8b36f8d34a1275e64a9dd174599b8a3427095190f9be869c297b95", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "http-not-https", "owasp": "A02:2021", "cwe_ids": ["CWE-319"], "precision": 0.917, "promoted_at": "2026-05-18T14:01:32.347999+00:00", "triaged_in_corpus": 12, "observations_count": 4113831, "ai_coder_pattern_id": 15}, "scanner": "repobility-threat-engine", "correlation_key": "fp|7953f2a6af8b36f8d34a1275e64a9dd174599b8a3427095190f9be869c297b95"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/services/integrations/aggregator/contacts/payloads/base_payload.rb"}, "region": {"startLine": 68}}}]}, {"ruleId": "MINED043", "level": "none", "message": {"text": "[MINED043] Http Not Https: Hardcoded http:// (not localhost) for endpoints that handle credentials or data."}, "properties": {"repobilityId": 91351, "scanner": "repobility-threat-engine", "fingerprint": "4944bb471a49613af4e89707fc78e6207bb90539645d2ca543115f6f920c1afb", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "http-not-https", "owasp": "A02:2021", "cwe_ids": ["CWE-319"], "precision": 0.917, "promoted_at": "2026-05-18T14:01:32.347999+00:00", "triaged_in_corpus": 12, "observations_count": 4113831, "ai_coder_pattern_id": 15}, "scanner": "repobility-threat-engine", "correlation_key": "fp|4944bb471a49613af4e89707fc78e6207bb90539645d2ca543115f6f920c1afb"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/serializers/e_invoices/factur_x/base_serializer.rb"}, "region": {"startLine": 7}}}]}, {"ruleId": "SEC015", "level": "none", "message": {"text": "[SEC015] Insecure Randomness for Security (and 3 more): Same pattern found in 3 additional files. Review if needed."}, "properties": {"repobilityId": 91350, "scanner": "repobility-threat-engine", "fingerprint": "ed3769a4ea3a3aeb3b1fd74c33a316d9452004c8aff6770390b3265ad0543e09", "category": "crypto", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 3 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 3 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|ed3769a4ea3a3aeb3b1fd74c33a316d9452004c8aff6770390b3265ad0543e09"}}}, {"ruleId": "SEC096", "level": "none", "message": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql (and 1 more): Same pattern found in 1 additional files. Review if needed."}, "properties": {"repobilityId": 91345, "scanner": "repobility-threat-engine", "fingerprint": "b77e3a6581c9257ba7c802907cad00905a197de25d4d0166437aa2d2de02f0a3", "category": "quality", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 1 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 1 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC096", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|b77e3a6581c9257ba7c802907cad00905a197de25d4d0166437aa2d2de02f0a3"}}}, {"ruleId": "SEC128", "level": "none", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake) (and 11 more): Same pattern found in 11 additional files. Review if needed."}, "properties": {"repobilityId": 91341, "scanner": "repobility-threat-engine", "fingerprint": "2a90f201efe0fa0c5dec20cc574f41ea779c24e8a2731e92a392ebdb37082c00", "category": "quality", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 11 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 11 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|2a90f201efe0fa0c5dec20cc574f41ea779c24e8a2731e92a392ebdb37082c00"}}}, {"ruleId": "SEC029", "level": "none", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 13 more): Same pattern found in 13 additional files. Review if needed."}, "properties": {"repobilityId": 91337, "scanner": "repobility-threat-engine", "fingerprint": "67207f5a6f091578506eace9ca6ffadd0a3f381d921b44ecf0b5e41c235e25c5", "category": "ssrf", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 13 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 13 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|67207f5a6f091578506eace9ca6ffadd0a3f381d921b44ecf0b5e41c235e25c5"}}}, {"ruleId": "SEC020", "level": "none", "message": {"text": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequent AI-assisted coding failure: the helper exposes the exact value needed for troubleshooting."}, "properties": {"repobilityId": 91333, "scanner": "repobility-threat-engine", "fingerprint": "bf3fd5c4f855338215140e3f1f81390b5227473d67674c335c8596bc793faccd", "category": "credential_exposure", "severity": "info", "confidence": 0.15, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Log message mentions credential-related metadata but does not print a credential-bearing value", "evidence": {"match": "logger.warn(\"Error renewing token: <redacted>}\")", "reason": "Log message mentions credential-related metadata but does not print a credential-bearing value", "rule_id": "SEC020", "scanner": "repobility-threat-engine", "confidence": 0.15, "correlation_key": "secret|token|5|logger.warn error renewing token: redacted"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/concerns/authenticable_user.rb"}, "region": {"startLine": 60}}}]}, {"ruleId": "MINED091", "level": "none", "message": {"text": "[MINED091] Ruby Rescue Bare: rescue without exception class catches StandardError too broadly."}, "properties": {"repobilityId": 91332, "scanner": "repobility-threat-engine", "fingerprint": "d4b647c3c08ad7f5552f44bdbf918926b9deb28bc0d15beaba14f771b79e4415", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "ruby-rescue-bare", "owasp": null, "cwe_ids": ["CWE-755"], "languages": ["ruby"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.348150+00:00", "triaged_in_corpus": 12, "observations_count": 280, "ai_coder_pattern_id": 163}, "scanner": "repobility-threat-engine", "correlation_key": "fp|d4b647c3c08ad7f5552f44bdbf918926b9deb28bc0d15beaba14f771b79e4415"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/services/inbound_webhooks/process_service.rb"}, "region": {"startLine": 34}}}]}, {"ruleId": "MINED091", "level": "none", "message": {"text": "[MINED091] Ruby Rescue Bare: rescue without exception class catches StandardError too broadly."}, "properties": {"repobilityId": 91331, "scanner": "repobility-threat-engine", "fingerprint": "5fdcc99b449a8ec6e8302d9ab3def59ba7cdd6bfc60931f5363886f0a52c874f", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "ruby-rescue-bare", "owasp": null, "cwe_ids": ["CWE-755"], "languages": ["ruby"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.348150+00:00", "triaged_in_corpus": 12, "observations_count": 280, "ai_coder_pattern_id": 163}, "scanner": "repobility-threat-engine", "correlation_key": "fp|5fdcc99b449a8ec6e8302d9ab3def59ba7cdd6bfc60931f5363886f0a52c874f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/graphql/types/charge_filters/values.rb"}, "region": {"startLine": 12}}}]}, {"ruleId": "MINED091", "level": "none", "message": {"text": "[MINED091] Ruby Rescue Bare: rescue without exception class catches StandardError too broadly."}, "properties": {"repobilityId": 91330, "scanner": "repobility-threat-engine", "fingerprint": "a4333ec7a8450bfcefda50a419a86063157b29748736b412347646b0180ddf75", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "ruby-rescue-bare", "owasp": null, "cwe_ids": ["CWE-755"], "languages": ["ruby"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.348150+00:00", "triaged_in_corpus": 12, "observations_count": 280, "ai_coder_pattern_id": 163}, "scanner": "repobility-threat-engine", "correlation_key": "fp|a4333ec7a8450bfcefda50a419a86063157b29748736b412347646b0180ddf75"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/application_controller.rb"}, "region": {"startLine": 57}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `aws-actions/amazon-ecr-login` pinned to mutable ref `@v2`: `uses: aws-actions/amazon-ecr-login@v2` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91439, "scanner": "repobility-supply-chain", "fingerprint": "7e075801847662e92d8bf508c911a9495c27be40a2dba7a2f4aabddeac6f88f0", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|7e075801847662e92d8bf508c911a9495c27be40a2dba7a2f4aabddeac6f88f0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/internal-build.yml"}, "region": {"startLine": 29}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `aws-actions/configure-aws-credentials` pinned to mutable ref `@v4`: `uses: aws-actions/configure-aws-credentials@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91438, "scanner": "repobility-supply-chain", "fingerprint": "84a9622d0deb90c7166d3d082303cb6b07b77b5b90e0d75f5ab7c0de1fc8571d", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|84a9622d0deb90c7166d3d082303cb6b07b77b5b90e0d75f5ab7c0de1fc8571d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/internal-build.yml"}, "region": {"startLine": 21}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/checkout` pinned to mutable ref `@v4`: `uses: actions/checkout@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91437, "scanner": "repobility-supply-chain", "fingerprint": "2b8c2f907656cf69bcf1714174bffb80c03591ea5fcd1d0008af3706f8551001", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|2b8c2f907656cf69bcf1714174bffb80c03591ea5fcd1d0008af3706f8551001"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/internal-build.yml"}, "region": {"startLine": 18}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `ruby/setup-ruby` pinned to mutable ref `@v1`: `uses: ruby/setup-ruby@v1` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91436, "scanner": "repobility-supply-chain", "fingerprint": "e8fdf9d2036aa9939d2e7ed5fde4763873306d2f7ecfd327f9980c859891e887", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|e8fdf9d2036aa9939d2e7ed5fde4763873306d2f7ecfd327f9980c859891e887"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/linters.yml"}, "region": {"startLine": 19}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/checkout` pinned to mutable ref `@v4`: `uses: actions/checkout@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91435, "scanner": "repobility-supply-chain", "fingerprint": "e209707a6ec7a8980a4eff55f4f1a1fc76f40471a9f2391b174f8059aede2e71", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|e209707a6ec7a8980a4eff55f4f1a1fc76f40471a9f2391b174f8059aede2e71"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/linters.yml"}, "region": {"startLine": 15}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `peter-evans/repository-dispatch` pinned to mutable ref `@v3`: `uses: peter-evans/repository-dispatch@v3` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91434, "scanner": "repobility-supply-chain", "fingerprint": "830e555f454b20d0026f825141571a5da1db3803f5fd41acc897f9631cf09e11", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|830e555f454b20d0026f825141571a5da1db3803f5fd41acc897f9631cf09e11"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 151}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/download-artifact` pinned to mutable ref `@v4`: `uses: actions/download-artifact@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91433, "scanner": "repobility-supply-chain", "fingerprint": "9e3a846f6cd414774c498014396184584e5eae6e4e0fb932f67d5ca1357a9456", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|9e3a846f6cd414774c498014396184584e5eae6e4e0fb932f67d5ca1357a9456"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 97}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/upload-artifact` pinned to mutable ref `@v4`: `uses: actions/upload-artifact@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91432, "scanner": "repobility-supply-chain", "fingerprint": "830c8b57a515fe8d5c14e9b97ec9d14823451bc1b5e7c4df7980bd6d9ab0e246", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|830c8b57a515fe8d5c14e9b97ec9d14823451bc1b5e7c4df7980bd6d9ab0e246"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 78}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/checkout` pinned to mutable ref `@v4`: `uses: actions/checkout@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91431, "scanner": "repobility-supply-chain", "fingerprint": "61ff742eca0fc0c03bf3dd50d8e4d3b04c7fc31c7464666c5deb4fc820ba4b84", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|61ff742eca0fc0c03bf3dd50d8e4d3b04c7fc31c7464666c5deb4fc820ba4b84"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 31}}}]}, {"ruleId": "MINED126", "level": "error", "message": {"text": "[MINED126] Workflow container/services image `getlago/postgres-partman:15.0-alpine` unpinned: `container/services image: getlago/postgres-partman:15.0-alpine` without `@sha256:...` pulls a mutable tag at workflow-run time. Treat workflow container references with the same supply-chain discipline as Dockerfile FROM lines."}, "properties": {"repobilityId": 91430, "scanner": "repobility-supply-chain", "fingerprint": "6acfa0ab0d17d287c84cfa48635927544d0e83432ca522cf00545ffd950ef86e", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-container-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|6acfa0ab0d17d287c84cfa48635927544d0e83432ca522cf00545ffd950ef86e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/migrations-test.yml"}, "region": {"startLine": 15}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `tj-actions/install-postgresql` pinned to mutable ref `@v3`: `uses: tj-actions/install-postgresql@v3` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91429, "scanner": "repobility-supply-chain", "fingerprint": "8420d5b83c3273aa0e6308919b934b7419d7c5c30aa8f6330dbbd5bd08134991", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|8420d5b83c3273aa0e6308919b934b7419d7c5c30aa8f6330dbbd5bd08134991"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/migrations-test.yml"}, "region": {"startLine": 51}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `ruby/setup-ruby` pinned to mutable ref `@v1`: `uses: ruby/setup-ruby@v1` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91428, "scanner": "repobility-supply-chain", "fingerprint": "4ac83b21a2f941003882f4833b79ec89e9768e255ddd2f45d8e4412f7682d1ba", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|4ac83b21a2f941003882f4833b79ec89e9768e255ddd2f45d8e4412f7682d1ba"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/migrations-test.yml"}, "region": {"startLine": 46}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/checkout` pinned to mutable ref `@v4`: `uses: actions/checkout@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91427, "scanner": "repobility-supply-chain", "fingerprint": "3e510ff2f47fec98b3ac2d29b96a4310c0f23f82eb5cae9a08e4c21af6d3d833", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|3e510ff2f47fec98b3ac2d29b96a4310c0f23f82eb5cae9a08e4c21af6d3d833"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/migrations-test.yml"}, "region": {"startLine": 44}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/setup-node` pinned to mutable ref `@v6`: `uses: actions/setup-node@v6` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91426, "scanner": "repobility-supply-chain", "fingerprint": "f55711dbe517a23b4e7a3c511457928f9d4dcafe1b291ca238f5248ca4c5ad93", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|f55711dbe517a23b4e7a3c511457928f9d4dcafe1b291ca238f5248ca4c5ad93"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/front-compatibility.yml"}, "region": {"startLine": 49}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `pnpm/action-setup` pinned to mutable ref `@v6`: `uses: pnpm/action-setup@v6` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91425, "scanner": "repobility-supply-chain", "fingerprint": "8da75a24fe45899778a2ad66eaeab18056af5793643c3b7262e3fcdb3d7dae4e", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|8da75a24fe45899778a2ad66eaeab18056af5793643c3b7262e3fcdb3d7dae4e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/front-compatibility.yml"}, "region": {"startLine": 41}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/checkout` pinned to mutable ref `@v6`: `uses: actions/checkout@v6` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91424, "scanner": "repobility-supply-chain", "fingerprint": "dc45742f49e374ba361d66e2695138e37c359997ed0b9400b87ddc9a8547e6d0", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|dc45742f49e374ba361d66e2695138e37c359997ed0b9400b87ddc9a8547e6d0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/front-compatibility.yml"}, "region": {"startLine": 34}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/checkout` pinned to mutable ref `@v6`: `uses: actions/checkout@v6` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91423, "scanner": "repobility-supply-chain", "fingerprint": "7abd97438d26c3906d132a06d1ee7c204c67b4089e1d5ec564c3840672b7c2a5", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|7abd97438d26c3906d132a06d1ee7c204c67b4089e1d5ec564c3840672b7c2a5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/front-compatibility.yml"}, "region": {"startLine": 28}}}]}, {"ruleId": "MINED126", "level": "error", "message": {"text": "[MINED126] Workflow container/services image `getlago/postgres-partman:15.0-alpine` unpinned: `container/services image: getlago/postgres-partman:15.0-alpine` without `@sha256:...` pulls a mutable tag at workflow-run time. Treat workflow container references with the same supply-chain discipline as Dockerfile FROM lines."}, "properties": {"repobilityId": 91422, "scanner": "repobility-supply-chain", "fingerprint": "96b728ff4f54d8cd1a42f7d3ca70600df22e1710668dc62df9a70d3dcd9232a2", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-container-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|96b728ff4f54d8cd1a42f7d3ca70600df22e1710668dc62df9a70d3dcd9232a2"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/spec.yml"}, "region": {"startLine": 15}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `ruby/setup-ruby` pinned to mutable ref `@v1`: `uses: ruby/setup-ruby@v1` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91420, "scanner": "repobility-supply-chain", "fingerprint": "def12800b28f190914c32ed20995967d471adc69d8e3c469c1cb960d51f240f5", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|def12800b28f190914c32ed20995967d471adc69d8e3c469c1cb960d51f240f5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/spec.yml"}, "region": {"startLine": 71}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `actions/checkout` pinned to mutable ref `@v4`: `uses: actions/checkout@v4` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"repobilityId": 91419, "scanner": "repobility-supply-chain", "fingerprint": "ba889e4ee951cc96ea75d429ad9ff2fd6c62fa4df94b6e6daed38e20f7398a70", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|ba889e4ee951cc96ea75d429ad9ff2fd6c62fa4df94b6e6daed38e20f7398a70"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/spec.yml"}, "region": {"startLine": 69}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "[MINED118] Dockerfile FROM `ruby:4.0.2-slim` not pinned by digest: `FROM ruby:4.0.2-slim` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"repobilityId": 91418, "scanner": "repobility-supply-chain", "fingerprint": "313113e14554a28d973d2cf9e4ac833364ba71b646e718d8d1dd1cf2b954f1ec", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|313113e14554a28d973d2cf9e4ac833364ba71b646e718d8d1dd1cf2b954f1ec"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile.dev"}, "region": {"startLine": 9}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "[MINED118] Dockerfile FROM `ruby:4.0.2-slim` not pinned by digest: `FROM ruby:4.0.2-slim` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"repobilityId": 91417, "scanner": "repobility-supply-chain", "fingerprint": "1672635fc153f67d0cafc03ef3f673ecf5b531a6f310d18e008146e851845458", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|1672635fc153f67d0cafc03ef3f673ecf5b531a6f310d18e008146e851845458"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 32}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "[MINED118] Dockerfile FROM `ruby:4.0.2-slim` not pinned by digest: `FROM ruby:4.0.2-slim` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"repobilityId": 91416, "scanner": "repobility-supply-chain", "fingerprint": "7084771619f625cf8f1d69f2f3a920ffbd49b579043a6feb7dfeacec1653e9d5", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|7084771619f625cf8f1d69f2f3a920ffbd49b579043a6feb7dfeacec1653e9d5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 9}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /payment_receipts/:id."}, "properties": {"repobilityId": 91394, "scanner": "repobility-access-control", "fingerprint": "3700a2ff358a2c63fc0397d69cfd361f034bb32303ee0582b0a249f2451e0f0f", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/payment_receipts/:id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|217|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 217}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /invoices/:id."}, "properties": {"repobilityId": 91393, "scanner": "repobility-access-control", "fingerprint": "ac8f19e584c760bac206ecdc4390d5663c09b91ef96342ae6f13c3b6d1a3303f", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/invoices/:id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|216|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 216}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /moneyhash/:organization_id."}, "properties": {"repobilityId": 91392, "scanner": "repobility-access-control", "fingerprint": "9735156ebeaef1544afe717ae42a2fcf8f51655cf30af2445b1dbe8a861b2a24", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/moneyhash/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|203|auc003", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 203}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /adyen/:organization_id."}, "properties": {"repobilityId": 91391, "scanner": "repobility-access-control", "fingerprint": "cf243a7b5313bfa80bdee679d37bfa5dd85930a12639e3c11b5b689365926874", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/adyen/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|202|auc003", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 202}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /gocardless/:organization_id."}, "properties": {"repobilityId": 91390, "scanner": "repobility-access-control", "fingerprint": "e504a06fd72f51e310e65c95c81fc6a42fd1acd81b94e0ac60efa6f6ed45dade", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/gocardless/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|201|auc003", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 201}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /flutterwave/:organization_id."}, "properties": {"repobilityId": 91389, "scanner": "repobility-access-control", "fingerprint": "9bec084a0bb537011fec5694f9cc0218dd2720cfe9b60aa28e5dc56d1ec1a538", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/flutterwave/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|200|auc003", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 200}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /cashfree/:organization_id."}, "properties": {"repobilityId": 91388, "scanner": "repobility-access-control", "fingerprint": "ec0532ab42503381ce6ccae5feb80413259d39f577381085d6f8a3c30fe3393f", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/cashfree/:organization_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|199|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 199}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /wallets/:id."}, "properties": {"repobilityId": 91387, "scanner": "repobility-access-control", "fingerprint": "c6a55ec25a8b1b04a8147e12583d2ec09cc062e966222d0f1202cc74db7be762", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/wallets/:id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|182|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 182}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /wallets/:id/wallet_transactions."}, "properties": {"repobilityId": 91386, "scanner": "repobility-access-control", "fingerprint": "be409b61f4c67c299f0450f08ea49e7202ce5a4c9465686fdc34bf7e8576fa19", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/wallets/:id/wallet_transactions", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|174|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 174}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: ANY /subscriptions/:external_id."}, "properties": {"repobilityId": 91385, "scanner": "repobility-access-control", "fingerprint": "31b1e4371948417bcab1382c9237c87229113309e9c6c920917f9c89722dafdc", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/subscriptions/:external_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|97|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 97}}}]}, {"ruleId": "DKR006", "level": "error", "message": {"text": "Dockerfile pipes a remote script into a shell"}, "properties": {"repobilityId": 91379, "scanner": "repobility-docker", "fingerprint": "14e7f9bea3fcb05f73e3278f0906f2988a7e0cc6e692879b84a51fd10abd337b", "category": "docker", "severity": "high", "confidence": 0.92, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "RUN instruction contains curl/wget piped into a shell.", "evidence": {"rule_id": "DKR006", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|14e7f9bea3fcb05f73e3278f0906f2988a7e0cc6e692879b84a51fd10abd337b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile.dev"}, "region": {"startLine": 15}}}]}, {"ruleId": "DKR006", "level": "error", "message": {"text": "Dockerfile pipes a remote script into a shell"}, "properties": {"repobilityId": 91370, "scanner": "repobility-docker", "fingerprint": "e03d11e5043ad7a64066f7857cf765c2822b181ff1a461b78d1c7c373b78c112", "category": "docker", "severity": "high", "confidence": 0.92, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "RUN instruction contains curl/wget piped into a shell.", "evidence": {"rule_id": "DKR006", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|e03d11e5043ad7a64066f7857cf765c2822b181ff1a461b78d1c7c373b78c112"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 17}}}]}, {"ruleId": "SEC128", "level": "error", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake): Async call invoked without `await` returns an unhandled Promise. The outer function resolves before the inner work completes \u2014 DB writes lost, emails not sent, race conditions. This is one of the top-3 errors AI coders make: they understand async-shape but drop the await keyword when chaining multiple ops. Surfaces as flaky tests or silently dropped data in production."}, "properties": {"repobilityId": 91340, "scanner": "repobility-threat-engine", "fingerprint": "9673f6225b641d625b98a4e76a4eeb5e930c21c56e5911bf18fb9343f9f622e0", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "ERROR_TYPE_MAPPING.fetch(exception.class, \"unknown\")", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|9673f6225b641d625b98a4e76a4eeb5e930c21c56e5911bf18fb9343f9f622e0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/pending_vies_check.rb"}, "region": {"startLine": 25}}}]}, {"ruleId": "SEC128", "level": "error", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake): Async call invoked without `await` returns an unhandled Promise. The outer function resolves before the inner work completes \u2014 DB writes lost, emails not sent, race conditions. This is one of the top-3 errors AI coders make: they understand async-shape but drop the await keyword when chaining multiple ops. Surfaces as flaky tests or silently dropped data in production."}, "properties": {"repobilityId": 91339, "scanner": "repobility-threat-engine", "fingerprint": "d96b38f6a609312905f799cc24d95a0a2c536a3678892a02422da0fbee05f4a1", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "authentication_methods.delete(method)", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|d96b38f6a609312905f799cc24d95a0a2c536a3678892a02422da0fbee05f4a1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/concerns/organizations/authentication_methods.rb"}, "region": {"startLine": 50}}}]}, {"ruleId": "SEC128", "level": "error", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake): Async call invoked without `await` returns an unhandled Promise. The outer function resolves before the inner work completes \u2014 DB writes lost, emails not sent, race conditions. This is one of the top-3 errors AI coders make: they understand async-shape but drop the await keyword when chaining multiple ops. Surfaces as flaky tests or silently dropped data in production."}, "properties": {"repobilityId": 91338, "scanner": "repobility-threat-engine", "fingerprint": "98ba625f7a62a5865de6f381beaa43d71ddb1bf8680952d441b8e6f966523715", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "cleaned_arguments.delete(arg_defn.keyword)", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|98ba625f7a62a5865de6f381beaa43d71ddb1bf8680952d441b8e6f966523715"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/graphql/types/base_input_object.rb"}, "region": {"startLine": 16}}}]}, {"ruleId": "SEC029", "level": "error", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes endpoints, file:// URIs), exfiltrate data, or pivot through your network. SSRF is OWASP A10:2021 and a frequent foothold in cloud breaches."}, "properties": {"repobilityId": 91336, "scanner": "repobility-threat-engine", "fingerprint": "226c7abee8792cbc6c4e61fcb780afa4dc07147361a4e4010c0a5afbb829669b", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(f", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|226c7abee8792cbc6c4e61fcb780afa4dc07147361a4e4010c0a5afbb829669b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/credit_note.rb"}, "region": {"startLine": 91}}}]}, {"ruleId": "SEC029", "level": "error", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes endpoints, file:// URIs), exfiltrate data, or pivot through your network. SSRF is OWASP A10:2021 and a frequent foothold in cloud breaches."}, "properties": {"repobilityId": 91335, "scanner": "repobility-threat-engine", "fingerprint": "fe283fd3031dcb55d631e3ad3a5a909b9520120ad0a24542797b6db2eaf40923", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(l", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|fe283fd3031dcb55d631e3ad3a5a909b9520120ad0a24542797b6db2eaf40923"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/billing_entity.rb"}, "region": {"startLine": 125}}}]}, {"ruleId": "SEC029", "level": "error", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes endpoints, file:// URIs), exfiltrate data, or pivot through your network. SSRF is OWASP A10:2021 and a frequent foothold in cloud breaches."}, "properties": {"repobilityId": 91334, "scanner": "repobility-threat-engine", "fingerprint": "0084ff0b5ba9b4d0630438aa36423e877e4000733bd56fef20b8e8c1789292c9", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(c", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|0084ff0b5ba9b4d0630438aa36423e877e4000733bd56fef20b8e8c1789292c9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/graphql/resolvers/auth/google/auth_url_resolver.rb"}, "region": {"startLine": 15}}}]}, {"ruleId": "SEC120", "level": "error", "message": {"text": "[SEC120] Hardcoded HMAC key or JWT signing secret: JWT/HMAC signing secret hardcoded in source. Anyone with source access can forge tokens; secret leaks via git history."}, "properties": {"repobilityId": 91329, "scanner": "repobility-threat-engine", "fingerprint": "924d37b4c9a2e7c5e85f777ff928bb413d809839b86b8bedd711984ef93fee16", "category": "credential_exposure", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "JWT.encode(\n      {\n        data: payload.to_json,\n        iss: issuer\n      },\n      RsaPrivateKey,", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC120", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "secret|app/models/webhook.rb|4|jwt.encode data: payload.to_json iss: issuer rsaprivatekey"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/webhook.rb"}, "region": {"startLine": 47}}}]}, {"ruleId": "SEC120", "level": "error", "message": {"text": "[SEC120] Hardcoded HMAC key or JWT signing secret: JWT/HMAC signing secret hardcoded in source. Anyone with source access can forge tokens; secret leaks via git history."}, "properties": {"repobilityId": 91328, "scanner": "repobility-threat-engine", "fingerprint": "15d3b854dfb289d4861e38ffb6e320672215405f8b06b86dfc07421cf0f56138", "category": "credential_exposure", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "JWT.encode(payload, RsaPrivateKey, \"RS256\")", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC120", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "secret|token|3|jwt.encode payload rsaprivatekey rs256"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/api/v1/organizations_controller.rb"}, "region": {"startLine": 37}}}]}, {"ruleId": "CORE_NO_TESTS", "level": "error", "message": {"text": "No test files found"}, "properties": {"repobilityId": 91327, "scanner": "repobility-core", "fingerprint": "0200e9918bc2a7bf9c116d0907e50ac3df640c758b93852cf1890ec6e14d870d", "category": "testing", "severity": "high", "confidence": null, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"rule_id": "CORE_NO_TESTS", "scanner": "repobility-core", "correlation_key": "repo|testing|core_no_tests"}}}, {"ruleId": "MINED116", "level": "error", "message": {"text": "[MINED116] Workflow uses `secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }` lets a PR from any fork exfiltrate the secret (modify a script, log the value, etc.). Use `pull_request_target` ONLY with strict checkout discipline (no fork code in the trusted context)."}, "properties": {"repobilityId": 91421, "scanner": "repobility-supply-chain", "fingerprint": "b6af7ca2cb500405e34fcb3b7d5041ef96462b3a9179b15a81d663119f90b8d0", "category": "dependency", "severity": "critical", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-pull-request-secrets", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|b6af7ca2cb500405e34fcb3b7d5041ef96462b3a9179b15a81d663119f90b8d0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/spec.yml"}, "region": {"startLine": 59}}}]}, {"ruleId": "SEC096", "level": "error", "message": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation enables SQL injection. Concept from Brakeman check_sql \u2014 re-authored from OWASP CWE-89."}, "properties": {"repobilityId": 91344, "scanner": "repobility-threat-engine", "fingerprint": "3311c7bcf3a64d1894c5792936c30e9276d01834364a0b7dda013bddfb525515", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".where(\"(key, value) IN (#{", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC096", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|3311c7bcf3a64d1894c5792936c30e9276d01834364a0b7dda013bddfb525515"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/queries/customers_query.rb"}, "region": {"startLine": 76}}}]}, {"ruleId": "SEC096", "level": "error", "message": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation enables SQL injection. Concept from Brakeman check_sql \u2014 re-authored from OWASP CWE-89."}, "properties": {"repobilityId": 91343, "scanner": "repobility-threat-engine", "fingerprint": "ddffe06fad3b1f75ba896f9d0111aa055a9c1a05774f2ee05cf039cc8b0e69e5", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".where(\"DATE((daily_usages.usage_date)#{at_time_zone}) = DATE(:timestamp#{", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC096", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|ddffe06fad3b1f75ba896f9d0111aa055a9c1a05774f2ee05cf039cc8b0e69e5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/daily_usage.rb"}, "region": {"startLine": 15}}}]}, {"ruleId": "SEC096", "level": "error", "message": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation enables SQL injection. Concept from Brakeman check_sql \u2014 re-authored from OWASP CWE-89."}, "properties": {"repobilityId": 91342, "scanner": "repobility-threat-engine", "fingerprint": "ead91eb4a9b61c4a531d0a6f2bb1b554e44b77b3ca388ceb23b308743f6749a8", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".where(\n          \"DATE(subscriptions.ending_at#{", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC096", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|ead91eb4a9b61c4a531d0a6f2bb1b554e44b77b3ca388ceb23b308743f6749a8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/jobs/clock/terminate_ended_subscriptions_job.rb"}, "region": {"startLine": 9}}}]}]}]}