Skip to main content

Scan layers

A deep scan runs six analysis layers in sequence. Each layer operates on the repository file tree, produces a list of findings, and respects a per-layer budget of 45 seconds (270 seconds total). This page describes what each layer analyses and how it works.

Shallow vs deep scan coverage

Shallow scans run five lightweight checks directly against the GitHub API (no clone). Deep scans clone the repository and run all eleven categories across six dedicated layers.

Category Shallow Deep Layer
governanceYesYesShallow check
dependency (basic)YesYesShallow check
code_quality (basic)YesYesShallow check
security (basic)YesYesShallow check
iac (basic)YesYesShallow check
dependency (CVE lookup)NoYesDependencyAnalyzer
secretNoYesSecretDetector
sastNoYesSASTEngine
iac (full rules)NoYesIaCScanner
licenseNoYesLicenseAuditor
qualityNoYesQualityAnalyzer

Layer execution order and timeouts

Deep layers run sequentially in this order:

  1. DependencyAnalyzer
  2. SecretDetector
  3. SASTEngine
  4. IaCScanner
  5. LicenseAuditor
  6. QualityAnalyzer

Each layer has a 45-second individual timeout. The total deep scan budget is 270 seconds. If a layer times out or raises an unhandled exception, it is skipped and the scan continues with the remaining layers. Partial results are always returned.

Layer 1: DependencyAnalyzer

Parses dependency manifests and queries the GitHub Advisory Database (GHSA) GraphQL API for known CVEs. Also flags unpinned dependency versions.

Supported manifest files

GHSA query batching

Pinned dependencies are queried in batches of 20 against the GHSA GraphQL API. CVE severity is mapped from GHSA's severity classification to ticketyboo severity levels (critical, high, medium, low).

Unpinned versions

A dependency is considered unpinned if its version specifier uses a range operator (>=, ^, ~, *) rather than an exact version. Unpinned dependencies are reported at severity medium.

Layer 2: SecretDetector

Scans source and configuration files for hardcoded credentials using two methods: regex pattern matching and Shannon entropy analysis.

Regex patterns

The layer matches against patterns for:

Shannon entropy

Strings that pass through regex filters are also checked for Shannon entropy. A string with entropy above 4.5 and length of at least 16 characters is flagged as a potential secret at severity high. This catches secrets that do not match known patterns (for example, randomly generated API keys).

Redaction

Detected secret values are redacted before storage. The finding records the pattern type, file path, and line number, but not the secret value itself.

Layer 3: SASTEngine

Static application security testing. Uses Python AST analysis for Python files and regex patterns for JavaScript, Go, and Ruby.

Python AST checks

CheckWhat it detectsSeverity
Command injectionsubprocess, os.system calls with unsanitised inputcritical
SQL injectionString concatenation in SQL queriescritical
Insecure deserializationpickle.loads, yaml.load without SafeLoaderhigh
Cross-site scriptingUnescaped user input in HTML renderinghigh
Path traversalUser-controlled file path operationshigh
Weak cryptographyMD5, SHA1 usage via hashlibmedium

File size limit

Files larger than 500 KB are skipped by the SAST layer. A finding is recorded at severity info noting that the file was too large to analyse.

Layer 4: IaCScanner

Analyses Terraform (HCL2) and CloudFormation (YAML/JSON) files for infrastructure security misconfigurations.

Terraform rules

CheckResource typeSeverity
S3 bucket without server-side encryptionaws_s3_buckethigh
S3 bucket with public ACLaws_s3_bucket_aclcritical
Security group with unrestricted ingress (0.0.0.0/0)aws_security_grouphigh
IAM policy with wildcard action (*)aws_iam_policyhigh
RDS instance with encryption disabledaws_db_instancehigh

CloudFormation rules

CheckResource typeSeverity
S3 bucket missing PublicAccessBlockAWS::S3::Buckethigh
Security group with unrestricted ingressAWS::EC2::SecurityGrouphigh

CloudFormation templates are identified by the presence of an AWSTemplateFormatVersion or Resources key. Terraform files are identified by the .tf extension. HCL2 parsing uses the python-hcl2 library.

Layer 5: LicenseAuditor

Detects license files, classifies them using SPDX identifiers, and flags compatibility issues.

License classification

License files (LICENSE, LICENSE.md, LICENSE.txt, COPYING) are read and matched against SPDX patterns. Classified licenses are reported at severity info. The following classifications trigger higher severity:

License typeSeverityReason
GPL v2, GPL v3, AGPL v3highStrong copyleft; may require source disclosure
LGPL v2.1, LGPL v3mediumWeak copyleft; linking restrictions
No license file detectedmediumAll rights reserved by default
License field mismatch (package.json vs LICENSE file)mediumInconsistent declared license

Layer 6: QualityAnalyzer

Measures code quality metrics for Python files using AST analysis. Also scans all text files for TODO and FIXME comments.

Python metrics

MetricThresholdSeverity
Cyclomatic complexity per function> 15 branchesmedium
Function length> 100 lineslow
File length> 500 lineslow
Type hint coverage< 50% of function parameters/returnslow
TODO/FIXME count> 5 per repositorylow

Cyclomatic complexity counts decision points (if, elif, for, while, except, with, and, or, assert) per function. A score of 15 indicates a function with high branching complexity that is typically harder to test and maintain.

Finding deduplication

After all layers complete, findings with identical (file_path, category, title) tuples are deduplicated to one finding. This prevents a finding reported by both a shallow check and a deep layer from being counted twice against a gate threshold.

Next steps