Findings API
Findings are the core output of Infracast's compliance engine. Each finding represents a rule violation — a specific resource failing a compliance check against one or more frameworks. Findings include the affected resource, the control it violates, severity, and a remediation recommendation.
Endpoints
| Method | Path | Description | Permission |
|---|---|---|---|
| GET | /api/v1/tenants/{tenantID}/findings | List findings with filters | findings:read |
| GET | /api/v1/tenants/{tenantID}/findings/{findingID} | Get a finding | findings:read |
| POST | /api/v1/tenants/{tenantID}/findings/run | Run the audit engine | audit:run |
| GET | /api/v1/tenants/{tenantID}/findings/scored | Findings with risk scores | findings:read |
| GET | /api/v1/tenants/{tenantID}/findings/{findingID}/remediation | AI remediation steps | findings:read |
| GET | /api/v1/tenants/{tenantID}/findings/{findingID}/terraform-patch | Terraform fix | findings:read |
| POST | /api/v1/tenants/{tenantID}/findings/{findingID}/accept | Accept risk | findings:write |
| POST | /api/v1/tenants/{tenantID}/findings/{findingID}/resolve | Mark resolved | findings:write |
List Findings
GET /api/v1/tenants/{tenantID}/findings
Returns a paginated, filterable list of compliance findings.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
framework | string | Filter by framework ID (e.g., nist-800-53, cis-aws, pci-dss) |
severity | string | Comma-separated severity levels: CRITICAL,HIGH,MEDIUM,LOW,INFO |
status | string | open, resolved, accepted, all (default: open) |
resource_type | string | Filter by node type (e.g., aws.s3.bucket) |
control_id | string | Filter by control ID (e.g., AC-2, 5.2) |
search | string | Search in title, description, or resource ID |
page | int | Page number (default: 1) |
per_page | int | Results per page (default: 50, max: 500) |
sort | string | Sort field: severity, created_at, resource_id. Prefix with - for descending |
Example Requests
# All critical and high findings across all frameworks
curl -H "Authorization: Bearer $TOKEN" \
"$API_URL/api/v1/tenants/acme-corp/findings?severity=CRITICAL,HIGH"
# NIST 800-53 findings, sorted by severity
curl -H "Authorization: Bearer $TOKEN" \
"$API_URL/api/v1/tenants/acme-corp/findings?framework=nist-800-53&sort=severity"
# Open PCI DSS findings for S3 buckets
curl -H "Authorization: Bearer $TOKEN" \
"$API_URL/api/v1/tenants/acme-corp/findings?framework=pci-dss&resource_type=aws.s3.bucket&status=open"
Example Response
{
"items": [
{
"id": "NIST-AC-2-STALE-ACCESS-KEY-aws:us-east-1:aws.iam.user:svc-deploy",
"rule_id": "NIST-AC-2-STALE-ACCESS-KEY",
"framework": "nist-800-53",
"control_id": "AC-2",
"severity": "HIGH",
"status": "open",
"title": "IAM access key unused for 90+ days",
"description": "IAM user 'svc-deploy' has an access key unused for 127 days (≥90).",
"resource_id": "aws:us-east-1:aws.iam.user:svc-deploy",
"resource_type": "aws.iam.user",
"resource_name": "svc-deploy",
"region": "us-east-1",
"account_id": "123456789012",
"remediation": "Deactivate or delete access keys unused for 90+ days per NIST AC-2.",
"first_seen": "2024-02-15T10:00:00Z",
"last_seen": "2024-03-16T08:30:00Z",
"created_at": "2024-02-15T10:00:00Z"
},
{
"id": "CIS-AWS-5.2-aws:us-east-1:aws.ec2.security_group:sg-0abc123",
"rule_id": "CIS-AWS-5.2",
"framework": "cis-aws",
"control_id": "5.2",
"severity": "HIGH",
"status": "open",
"title": "Security group allows unrestricted SSH access",
"description": "Security group 'web-servers-sg' (sg-0abc123) has an inbound rule permitting SSH (port 22) from 0.0.0.0/0.",
"resource_id": "aws:us-east-1:aws.ec2.security_group:sg-0abc123",
"resource_type": "aws.ec2.security_group",
"resource_name": "web-servers-sg",
"region": "us-east-1",
"account_id": "123456789012",
"remediation": "Remove the 0.0.0.0/0 inbound rule for port 22. Restrict SSH to a bastion host or known admin CIDR ranges.",
"first_seen": "2024-03-10T14:00:00Z",
"last_seen": "2024-03-16T08:30:00Z",
"created_at": "2024-03-10T14:00:00Z"
}
],
"total": 287,
"page": 1,
"per_page": 50,
"total_pages": 6
}
Finding Severity
Findings are assigned one of five severity levels:
| Severity | Description | Typical Response Time |
|---|---|---|
| CRITICAL | Direct path to data breach or account compromise | Immediate (hours) |
| HIGH | Significant control failure, exploitable with low effort | 24–48 hours |
| MEDIUM | Control gap that increases risk but requires additional factors | 1–2 weeks |
| LOW | Defense-in-depth gap, minimal immediate risk | 30–90 days |
| INFO | Informational, no direct risk | Backlog / best effort |
Framework Mapping
A single finding can map to multiple framework controls. When a resource fails, Infracast surfaces the cross-framework impact:
GET /api/v1/tenants/acme-corp/findings/CIS-AWS-5.2-sg-0abc123
{
"id": "CIS-AWS-5.2-aws:us-east-1:aws.ec2.security_group:sg-0abc123",
"rule_id": "CIS-AWS-5.2",
"framework_mappings": [
{ "framework": "cis-aws", "control_id": "5.2" },
{ "framework": "nist-800-53", "control_id": "SC-7" },
{ "framework": "pci-dss", "control_id": "Req 1.3.2" },
{ "framework": "soc2", "control_id": "CC6.3" }
],
...
}
Run the Audit Engine
Trigger an immediate audit run against the current infrastructure graph:
POST /api/v1/tenants/{tenantID}/findings/run
{
"framework": "nist-800-53" # Optional: run only one framework
}
# Or run all frameworks
POST /api/v1/tenants/{tenantID}/findings/run
{}
Response:
{
"job_id": "audit-job-abc123",
"status": "running",
"frameworks": ["nist-800-53", "cis-aws", "pci-dss", "soc2"],
"started_at": "2024-03-16T10:00:00Z"
}
Get AI Remediation
Infracast provides detailed, AI-enhanced remediation steps for each finding:
GET /api/v1/tenants/{tenantID}/findings/{findingID}/remediation
{
"finding_id": "CIS-AWS-5.2-sg-0abc123",
"summary": "Remove the unrestricted SSH inbound rule and restrict to specific CIDR ranges.",
"steps": [
{
"order": 1,
"action": "Identify all EC2 instances using this security group",
"command": "aws ec2 describe-instances --filters 'Name=instance.group-id,Values=sg-0abc123'"
},
{
"order": 2,
"action": "Revoke the unrestricted SSH rule",
"command": "aws ec2 revoke-security-group-ingress --group-id sg-0abc123 --protocol tcp --port 22 --cidr 0.0.0.0/0"
},
{
"order": 3,
"action": "Add a restricted rule for your admin CIDR range",
"command": "aws ec2 authorize-security-group-ingress --group-id sg-0abc123 --protocol tcp --port 22 --cidr 10.0.0.0/8"
}
],
"terraform_patch_available": true
}
Get Terraform Patch
GET /api/v1/tenants/{tenantID}/findings/{findingID}/terraform-patch
{
"finding_id": "CIS-AWS-5.2-sg-0abc123",
"patch": "--- a/security_groups.tf\n+++ b/security_groups.tf\n@@ -15,8 +15,8 @@\n ingress {\n- from_port = 22\n- to_port = 22\n- protocol = \"tcp\"\n- cidr_blocks = [\"0.0.0.0/0\"]\n+ from_port = 22\n+ to_port = 22\n+ protocol = \"tcp\"\n+ cidr_blocks = [\"10.0.0.0/8\"] # Restricted to internal only\n }"
}
Accept Risk
When a finding cannot be remediated (legacy system, compensating control, risk accepted):
POST /api/v1/tenants/{tenantID}/findings/{findingID}/accept
{
"justification": "Legacy jump server scheduled for decommission Q3 2024. Compensating control: Security group only applied to isolated legacy VLAN.",
"review_date": "2024-09-30",
"approved_by": "ciso@company.com"
}
Accepted findings are excluded from compliance scoring but remain visible to auditors with full justification history.
Real-Time Findings Stream
Subscribe to findings as they are created (Server-Sent Events):
GET /api/v1/tenants/{tenantID}/findings/stream
# Events are streamed as:
data: {"event":"finding.created","finding":{"id":"...","severity":"HIGH",...}}
data: {"event":"finding.resolved","finding_id":"...","resolved_at":"2024-03-16T10:05:00Z"}
Findings Summary by Framework
GET /api/v1/tenants/{tenantID}/compliance/summary
{
"overall_score": 83,
"total_findings": 287,
"by_severity": {
"CRITICAL": 3,
"HIGH": 47,
"MEDIUM": 164,
"LOW": 73
},
"by_framework": {
"nist-800-53": { "score": 82, "findings": 94 },
"cis-aws": { "score": 84, "findings": 62 },
"pci-dss": { "score": 88, "findings": 78 },
"soc2": { "score": 91, "findings": 52 }
}
}
Python Example
from infracast import InfracastClient
client = InfracastClient(api_url="https://api.infracast.io", api_token="your-token")
# Get all critical findings
findings = client.findings.list(
tenant="acme-corp",
severity=["CRITICAL", "HIGH"],
status="open"
)
# Group by framework
by_framework = {}
for finding in findings:
fw = finding.framework
by_framework.setdefault(fw, []).append(finding)
for framework, fw_findings in by_framework.items():
print(f"{framework}: {len(fw_findings)} critical/high findings")
# Accept a risk
client.findings.accept_risk(
tenant="acme-corp",
finding_id="CIS-AWS-5.2-sg-0abc123",
justification="Legacy system, decommission scheduled Q3 2024",
review_date="2024-09-30"
)
Next Steps
- Nodes API — Get details on the affected resource
- Reports API — Generate compliance reports from findings
- Discovery Jobs API — Schedule automatic scans to keep findings current