IaC Security Misconfiguration Scanner API avatar

IaC Security Misconfiguration Scanner API

Pricing

from $0.35 / completed iac policy scan

Go to Apify Store
IaC Security Misconfiguration Scanner API

IaC Security Misconfiguration Scanner API

Scan Terraform, Kubernetes, Dockerfile, Helm, CloudFormation, and 15 more Infrastructure-as-Code formats for security misconfigurations. Submit a GitHub repository or ZIP and get normalized Checkov findings plus an automation-ready JSON summary. Start your first scan now. No runner to maintain.

Pricing

from $0.35 / completed iac policy scan

Rating

0.0

(0)

Developer

KazKN

KazKN

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

19 hours ago

Last modified

Share

One unsafe line in Infrastructure as Code (IaC), such as Terraform, Kubernetes, CloudFormation, Helm, Dockerfile, or CI configuration, can create public exposure, weaken IAM, disable encryption, open a network path, or remove logging. Paste a GitHub repository or upload a ZIP. This IaC-only Actor runs the pinned Checkov 3.3.8 policy scanner and reports the failed policy, file, affected resource, and line range when Checkov provides one.

The result is ready for people and automation: one Dataset row per failed policy, plus an OUTPUT JSON summary with a PASS, FAIL, or UNKNOWN policy gate. It is built for platform engineers, DevSecOps teams, cloud security teams, and automation builders who want a hosted scan without maintaining Checkov infrastructure.

Run the prefilled example or keep reading for a tested public GitHub example. The French owner guide explains IaC, every input, and every result in plain French.

Available on the Apify Store. The released cloud build was verified successfully on Apify.

🚀 Run your first scan

The public GitHub prefilled example is already complete. Do not change it for the first run.

  1. Open the prefilled Actor input.
  2. When the input page opens, click Start.
  3. Open the Dataset to see failed policies.
  4. Open OUTPUT to see the scan status, totals, warnings, and gateDecision.

Click the preview to open the tested public Terraform Example on Apify:

Public Terraform scan example on Apify

The published prefill scans a small Terraform fixture at an immutable Git commit:

{
"sourceType": "github",
"repositoryUrl": "https://github.com/DataKazKN/iac-security-scan-examples",
"repositoryRef": "ad600c04599f8a1d353639252ee12d2a5976a732",
"subdirectory": "fixtures/terraform",
"frameworks": ["terraform"],
"policyProfile": "security",
"maxFindings": 25
}

COMPLETED_WITH_FINDINGS is a successful scan: Checkov completed and found policy failures. FAILED means a validation, acquisition, scanner, persistence, billing, or internal technical failure.

This is a policy-result gate. FAIL means at least one Checkov policy failed; it is not a severity, exploitability, or compliance verdict.

The 60-second setup is a quick-start target, not a runtime promise. The Checkov subprocess itself has a hard timeout of 60 seconds; acquisition, persistence, and Actor lifecycle work are separate.

📊 What you receive

The Dataset is the fastest place to triage failures. Each row includes the Checkov policy, affected resource, file, line range, native category, and a stable fingerprint.

{
"checkId": "CKV_AWS_20",
"checkName": "S3 Bucket has an ACL defined which allows public READ access",
"resource": "aws_s3_bucket.public_example",
"filePath": "main.tf",
"lineStart": 1,
"lineEnd": 8,
"primaryCategory": "GENERAL_SECURITY",
"result": "FAILED"
}

OUTPUT answers whether the scanner completed and whether an automated workflow should continue:

{
"status": "COMPLETED_WITH_FINDINGS",
"gateDecision": "FAIL",
"passedCount": 0,
"failedCount": 1,
"findingCount": 1,
"totalFindingCount": 1,
"truncated": false
}
What you need to knowWhere to find it
Which policy failed and whereDataset: checkId, checkName, resource, filePath, lineStart, lineEnd
Whether the scan itself workedstatus in OUTPUT
Whether an automated workflow should continuegateDecision in OUTPUT
Whether some rows were omittedfindingCount, totalFindingCount, truncated, and truncationReasons
Which source was scannedPinned GitHub ref or ZIP statistics in source

This preview is rendered from the eight normalized findings in the public Terraform Example Dataset. Click it to inspect the source JSON:

Real normalized Terraform findings from the public Apify Dataset

This Actor is useful for a one-off repository review, a scheduled drift check, a pre-deployment API gate, or a saved Apify Task. It does not replace a live cloud posture management tool, secrets scanner, dependency scanner, or human security review.

💳 Pricing: $0.25-$0.50 per completed scan

One completed scan costs $0.50 on Apify Free and less on higher subscription tiers. A valid scan with zero findings is still a completed scan. The number of findings does not change the custom event price.

Apify subscription tiercompleted-scan price
Free$0.50
Bronze$0.45
Silver$0.40
Gold$0.35
Platinum$0.30
Diamond$0.25

Ten completed scans cost $5.00 in custom scan events on Free, or $3.50 on Gold, plus the small Actor-start event and platform compute. A single completed scan uses one completed-scan event, whether it returns one finding or 500.

Pricing: one successfully persisted completed-scan costs $0.25-$0.50 according to the customer's Apify subscription tier, plus the configured Actor-start platform event.

🎯 Choose your source and scan scope

Scan a public GitHub repository

Public sources should use a full commit SHA for a reproducible snapshot. Branches and tags are accepted but can move between runs.

{
"sourceType": "github",
"repositoryUrl": "https://github.com/hashicorp-education/learn-terraform-resources",
"repositoryRef": "0bc010155586c0012b33b51de03384d9d5129cb1",
"frameworks": ["terraform"],
"policyProfile": "security",
"checkIds": [],
"maxFindings": 500
}

The committed copy is examples/input-public-github.json. The Actor downloads a GitHub archive snapshot; it does not clone, run hooks, follow submodules, or modify the repository.

Scan an uploaded ZIP

ZIP uploads in Console use the ZIP file picker. Apify stores the upload in a Key-Value Store and supplies its canonical record URL. API clients must first upload the ZIP to a Key-Value Store, then pass that Key-Value Store record URL as archiveFile; generic URLs and local paths are rejected.

{
"sourceType": "zip_upload",
"archiveFile": "https://api.apify.com/v2/key-value-stores/YOUR_STORE_ID/records/YOUR_ARCHIVE.zip",
"frameworks": ["terraform"],
"policyProfile": "security",
"checkIds": [],
"maxFindings": 500
}

Only ZIP is supported. The Actor reads the parsed storage identifiers through the authenticated Apify storage client rather than fetching the pasted value as a general-purpose URL.

Ready-to-upload deterministic smoke ZIP

Download iac-public-s3-smoke.zip from the public fixture repository and select it in the Console ZIP file picker. Its SHA-256 is a76ff04581fa24a8f8843500c38f22f6e64cd1a1e433d373b87ef17092199756.

Safety warning: this fixture is intentionally vulnerable and exists only to test the scanner. It defines a public S3 bucket. Treat it as test data and never deploy it to AWS or any other environment.

Use these exact Console parameters:

{
"sourceType": "zip_upload",
"frameworks": ["terraform"],
"policyProfile": "security",
"checkIds": ["CKV_AWS_20"],
"maxFindings": 500
}

The file picker fills archiveFile with the authenticated Key-Value Store record. Expected result with the pinned local contract: COMPLETED_WITH_FINDINGS, gateDecision = FAIL, 0 passed, 1 failed, one Dataset row, native category GENERAL_SECURITY, and check ID CKV_AWS_20. This is an intentionally failing policy test and is not proof of cloud runtime or billing.

Scan a private GitHub repository

Use a fine-grained GitHub token with read-only Contents access to only the target repository. Do not grant write, administration, workflow, package, or organization permissions. The token is a secret input and is sent only to the GitHub API host; it is removed before an allowed archive-host redirect.

{
"sourceType": "github",
"repositoryUrl": "https://github.com/YOUR-ORGANIZATION/YOUR-PRIVATE-REPOSITORY",
"repositoryRef": "YOUR-FULL-40-CHARACTER-COMMIT-SHA",
"githubToken": "YOUR_GITHUB_TOKEN",
"frameworks": ["terraform"],
"policyProfile": "security",
"checkIds": [],
"maxFindings": 500
}

Never put the token in the repository URL, ref, ZIP, task name, webhook, or logs.

Supported frameworks and hard limits

Limits: ZIP uploads are capped at 20 MiB, scans retain up to 500 Dataset findings, and the Checkov subprocess has a 60-second timeout.

Choose one or more of these pinned V2 framework slugs:

FrameworkConsole label
ansibleAnsible
argo_workflowsArgo Workflows
armAzure Resource Manager (ARM)
azure_pipelinesAzure Pipelines
bicepBicep
bitbucket_pipelinesBitbucket Pipelines
cdkAWS CDK
circleci_pipelinesCircleCI Pipelines
cloudformationAWS CloudFormation
dockerfileDockerfile
github_actionsGitHub Actions
gitlab_ciGitLab CI
helmHelm
kubernetesKubernetes
kustomizeKustomize
openapiOpenAPI
serverlessServerless Framework
terraformTerraform
terraform_jsonTerraform JSON
terraform_planTerraform Plan

Hard runtime and archive bounds:

  • 20 MiB compressed ZIP.
  • 500 files maximum; every materialized entry must be a regular file (500 regular files).
  • 100 MiB total uncompressed.
  • 50 MiB per file.
  • 100:1 expansion ratio, both aggregate and per file.
  • 240 characters per path.
  • 1,000 central-directory entries and a 1 MiB central directory before extraction.
  • 32 MiB stdout and 1 MiB stderr from Checkov.
  • 60 seconds from subprocess spawn through exit and pipe EOF.
  • Up to 100 unique checkIds and 1–500 retained findings.

Only stored or deflated, unencrypted ZIP entries are allowed. Nested archives, absolute or traversing paths, symlinks, devices, path collisions, and unsupported compression are rejected before scanning.

🧪 Tested public Tasks

Each public Task below uses a credential-free input pinned to an immutable fixture commit. Its release verification run succeeded in the Apify cloud on 2026-07-22 and produced a non-empty Dataset of deliberate test findings.

Broad scans and automation

🤖 Automation

Start a run through the Apify API with your own Actor ID and token:

curl --request POST \
"https://api.apify.com/v2/acts/$ACTOR_ID/runs" \
--header "Authorization: Bearer $APIFY_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{"sourceType":"github","repositoryUrl":"https://github.com/hashicorp-education/learn-terraform-resources","repositoryRef":"0bc010155586c0012b33b51de03384d9d5129cb1","frameworks":["terraform"]}'

Use a run as a pre-deployment IaC security check: stop promotion when gateDecision is FAIL, and treat UNKNOWN as a technical gate that needs review. This is a policy-result gate. FAIL means at least one Checkov policy failed; it is not a severity, exploitability, or compliance verdict. After a run finishes, use the returned Dataset and Key-Value Store IDs to read findings and OUTPUT. For recurring drift checks: Create a saved Task from the same validated input, manage it with Apify Tasks, attach it to schedules, and add run-finished webhooks to your own workflow. An MCP client can call the same Actor through a separately configured Apify MCP integration.

Reusable public resources:

Click the workflow to open the prefilled Actor input:

IaC scan workflow from source to Dataset and automation gate

🔒 Security, retention, and limitations

  • Read-only source: the Actor does not modify your repository. It fetches a GitHub archive or reads one authenticated Apify Key-Value Store record. It never runs git clone, repository hooks, custom checks, or user-provided commands.
  • Bounded output: Dataset and OUTPUT exclude the raw scanner payload, raw source code, source excerpts, repository URL, GitHub token, evaluated variables, code blocks, raw definitions, credentials, stack traces, and arbitrary scanner metadata.
  • Ephemeral workspace: downloaded bytes, extracted files, trusted config, and temporary scanner state stay in one private workspace. The temporary source is cleaned before results are persisted and before charging. This is logical deletion, not secure physical erasure.
  • Stored results: normalized Dataset rows and OUTPUT remain after the run; retention is controlled by Apify storage. Review Apify storage retention and delete those records according to your own policy. A ZIP uploaded before the run is a caller-owned KVS record and is not deleted by this Actor.
  • Token handling: a private token is kept out of URLs, subprocess arguments, Checkov environment, output, and intentional logs. It is sent only to the GitHub API host and stripped before an allowed archive redirect.
  • Scanner isolation: the Actor fixes Checkov arguments and environment, disables external modules/checks and recognized network-backed paths, and does not provide kernel-level egress isolation. The allowlist cannot guarantee that future unknown network behavior will be blocked.
  • Filesystem boundary: private 0700 workspaces, directory descriptors, O_NOFOLLOW, O_EXCL, and identity checks defend against hostile archive paths and ordinary races. The Actor isolates hostile ZIP content inside its private temporary workspace, but does not defend against a malicious process with the same OS identity concurrently modifying that workspace between POSIX syscalls.

Known limitations and false positives

  • Checkov policies can produce false positives and false negatives. Review the resource, file, lines, policy name, native categories, and pinned source reference before remediation. A source reference is not a step-by-step remediation guide.
  • Keep Checkov in CI when you need pull-request feedback, organization-specific policy configuration, baseline management, suppressions, or a release gate. This Actor is a bounded hosted batch scan, not a CI replacement.
  • This IaC-only Actor does not scan secrets, dependencies/SCA, container images, running containers, cloud accounts, or live cloud posture/CSPM. It does not support custom Python checks, external checks, arbitrary Checkov configuration, or Terraform external-module downloads.
  • Severity is deliberately UNRATED: Checkov severity requires platform integration and an API key that this Actor does not accept. Do not treat UNRATED as low risk. The Actor provides no exploitable severity ranking and no verified compliance mapping.
  • The Actor does not fix code, open pull requests, create webhooks, host a dashboard, or persist a repository connection.
  • Helm and Kustomize use the pinned image tools and were verified in the released Apify cloud build. Continue to monitor their upstream tool compatibility.
  • Checkov 3.3.8 currently locks vulnerable transitive dependency lines: aiohttp cannot yet move to the required patched line, and ecdsa has no upstream fixed release in this lock. These are monitored dependency limitations of the pinned scanner stack.

❓ FAQ and error reference

Does a policy failure mean the Actor failed?

No. A result with failed policies uses COMPLETED_WITH_FINDINGS and is a delivered, successful scan. Inspect the Dataset, then triage each policy.

Why did I receive fewer Dataset rows than the total?

maxFindings limits retained rows. totalFindingCount, truncated, and truncationReasons preserve the distinction.

Should I rerun after a billing error?

Use the action in the marked error table. The result may already have been saved and the charge outcome can be ambiguous.

Error codeLikely causeWhat to do
INPUT_SOURCE_EXCLUSIVESource fields are missing, mixed, or inconsistent with sourceType.Provide exactly one matching GitHub or ZIP source.
ARCHIVE_TOO_LARGEThe compressed archive exceeds 20 MiB.Create a smaller ZIP with only the IaC files to scan.
ARCHIVE_UNSUPPORTEDThe file is not a supported plain ZIP.Re-create it as an unencrypted stored/deflated ZIP.
ARCHIVE_UNSAFE_ENTRYA path, link, special file, collision, encryption flag, or nested archive is unsafe.Remove the unsafe entry and rebuild the ZIP.
ARCHIVE_EXPANSION_LIMITDeclared or actual expansion exceeds the byte or ratio bounds.Reduce large or highly compressed files.
FILE_LIMIT_EXCEEDEDThe archive exceeds the regular-file or central-directory entry limit.Keep only the source files needed for this scan.
REPO_NOT_ALLOWEDThe repository URL is not an exact supported GitHub URL.Use https://github.com/{owner}/{repository} without credentials or query data.
REF_INVALIDThe branch, tag, or commit ref is syntactically unsafe.Use a valid ref; prefer a full 40-character commit SHA.
SOURCE_FILE_NOT_ALLOWEDThe upload reference is not a canonical Apify KVS record.Upload through Console or pass the exact KVS record URL.
AUTH_FAILEDGitHub token rejected, or Apify KVS returned 401/403 for the uploaded record.Inspect the token or KVS permissions and confirm that the record still exists and is accessible.
FETCH_FAILEDGitHub or Apify storage acquisition did not complete safely.Verify source availability and retry once.
FRAMEWORK_UNSUPPORTEDA framework is unknown, excluded, or duplicated.Select unique values from the supported framework list.
CHECK_ID_INVALIDA check ID is malformed, unknown, duplicated, or outside the selected frameworks.Correct the IDs or leave the list empty.
SCAN_ABORTEDThe Actor was aborted or migrated before delivery.Start a new run when capacity is stable.
SCAN_TIMEOUTCheckov exceeded the 60-second subprocess limit.Reduce the repository or scan fewer frameworks/checks.
SCAN_RESOURCE_LIMITCheckov stdout or stderr exceeded its hard cap.Narrow the scan scope and retry.
CHECKOV_FAILEDA dependency tool, preflight, signal, or unsupported Checkov exit prevented a complete scan.Check the selected frameworks and retry only after correcting the scope.
CHECKOV_OUTPUT_INVALIDCheckov returned empty, malformed, unsafe, or structurally invalid JSON.Record the run details and report a reproducible case.
OUTPUT_PERSIST_FAILEDDataset or OUTPUT could not be stored safely.Check Apify storage status before a new run.
BILLING_FAILEDThe result was persisted but the billing call was ambiguous or invalid.Inspect OUTPUT before rerunning; do not assume the result or charge is absent.
INTERNAL_ERRORAn unexpected failure was sanitized.Retry once; report a reproducible failure without sharing secrets.

📄 Technical reference and verification

The default Dataset contains one normalized row per failed policy, up to maxFindings. Passed and skipped policies appear only as counters in OUTPUT. The normalizer builds every row from an allowlist; it does not copy arbitrary scanner objects.

Dataset finding fields

FieldMeaning
schemaVersionContract version, currently 2.
scanIdRun-scoped identifier shared with OUTPUT.
findingTypeAlways IAC_MISCONFIGURATION.
policyProfileApplied profile: security or all_iac.
frameworkCheckov framework that produced the finding.
checkIdStable Checkov policy identifier.
checkNameHuman-readable policy name.
resourceNormalized affected resource name.
filePathRelative POSIX path inside the snapshot.
lineStartFirst affected line, or null.
lineEndLast affected line, or null.
checkovCategoriesComplete ordered native Checkov category list.
primaryCategoryFirst native category, used once in summary totals.
severityUNRATED; no exploitable severity is invented.
findingFingerprintStable SHA-256 excluding scan ID and line numbers.
policyReferencePinned Checkov source reference, not a remediation promise.
resultAlways FAILED for a Dataset row.
scannerVersionPinned Checkov version, currently 3.3.8.

OUTPUT fields

FieldMeaning
schemaVersionContract version, currently 2.
scanIdRun-scoped scan identifier.
statusCOMPLETED, COMPLETED_WITH_FINDINGS, or FAILED.
policyProfileApplied profile: security or all_iac.
gateDecisionPASS without findings, FAIL with findings, UNKNOWN on technical failure.
scannerScanner name, Checkov.
scannerVersionExact scanner version, 3.3.8.
frameworksSelected framework slugs.
durationMsBounded scanner duration in milliseconds.
sourceBounded source statistics described below.
passedCountPolicies reported passed.
failedCountPolicies reported failed.
skippedCountPolicies reported skipped.
findingCountDataset findings retained after maxFindings.
totalFindingCountComplete normalized failed-finding count.
findingsByCategoryFull finding totals by deterministic primary category; sums to totalFindingCount.
truncatedWhether findings were limited.
truncationReasonsStable reasons for truncation.
warningsSafe normalization warnings.
errorSafe technical error on FAILED; omitted on success.

Nested source fields

FieldMeaning
kindgithub, zip_upload, or unknown on an early failure.
compressedBytesBounded downloaded or uploaded archive bytes.
fileCountBounded extracted regular-file count.
uncompressedBytesBounded extracted bytes.

Nested error fields

FieldMeaning
codeStable public technical error code.
messageShort safe user-facing message.
hintOptional safe corrective hint.

Billing details

Failures before the custom billing call do not trigger completed-scan; the configured Actor-start platform event can still apply. The active Pay-Per-Event configuration also lists Apify's recommended apify-actor-start at USD 0.00005 per 1 GB start event. apify-default-dataset-item is not configured. At the current 4 GB memory setting, the Actor-start total is USD 0.00020.

The Actor persists Dataset rows and OUTPUT, cleans the temporary source, then calls the custom event once per process invocation. Use minimalMaxTotalChargeUsd = 0.51 and maxTotalChargeUsd = 0.51 for bounded runs. Apify resolves the customer's tier into the effective event price supplied to a cloud run.

Apify SDK 4.0.0 can record synthetic default-Dataset-item events in its local simulator, but local simulation does not prove the cloud-resolved tier or live billing. The separately verified live configuration contains apify-actor-start and completed-scan, with no configured apify-default-dataset-item price.

If the spending limit prevents the event, the Actor treats it as a billing failure because charged_count must be exactly 1. The Dataset and OUTPUT were persisted before the billing call and may still exist. If the billing call is ambiguous, inspect OUTPUT before rerunning and do not assume the charge is absent. The Actor fails instead of retrying a possibly charged event.

Verification anchors

The simplified Dataset and OUTPUT examples above come from a separate sanitized Cyber V2 contract fixture. The complete field contract is defined by the marked tables in this section.

Cyber V2 contract fixture (2026-07-21): Checkov 3.3.8 scanned the committed public-S3 Terraform fixture with only CKV_AWS_20: 0 passed, 1 failed, and 1/1 finding. The native category is GENERAL_SECURITY; the stable fingerprint is 1affa58e43cf0f2e522ca5512be90f664891cf6be68020bcf9bca988860b9f4b.

Anchors: sanitized local artifacts for OUTPUT and the Dataset row, including source SHA-256 provenance.

This sanitized local smoke fixture demonstrates the Cyber V2 Dataset-row and OUTPUT-summary contract only. It does not prove Apify storage, runtime OUTPUT persistence, or billing.

Verified local apify run (2026-07-21): Using the committed examples/input-public-github.json pinned public GitHub source and Checkov 3.3.8, the local Apify flow reported 3 passed and 5 failed policies, persisted 5 Dataset rows, and wrote OUTPUT with COMPLETED_WITH_FINDINGS, gateDecision = FAIL, and category totals ENCRYPTION=1, GENERAL_SECURITY=2, IAM=1, LOGGING=1.

The run recorded exactly one manual/local completed-scan event. The simulator also produced five synthetic apify-default-dataset-item events. This local simulator trace does not prove cloud pricing. The live Pay-Per-Event configuration was verified on 2026-07-24 to contain apify-actor-start and completed-scan.

Checkov attribution

This Actor wraps the upstream Checkov 3.3.8 command-line scanner. Checkov is licensed under Apache-2.0. IaC Security Misconfiguration Scanner API and KazKN are not affiliated with, endorsed by, or sponsored by the Checkov maintainers or Palo Alto Networks. See THIRD_PARTY_NOTICES.md for attribution and license details.

▶️ Run the Actor

Start the prefilled scan in Apify Console

Run IaC Security Misconfiguration Scanner API on Apify