{"components":{"parameters":{"AssessmentId":{"in":"path","name":"assessmentId","required":true,"schema":{"format":"uuid","type":"string"}},"BatchId":{"description":"The producer's id for the batch, unique within the assessment.","in":"path","name":"batchId","required":true,"schema":{"pattern":"^[A-Za-z0-9._:-]{1,100}$","type":"string"}},"Cursor":{"description":"The next_cursor of the previous page.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},"DomainId":{"in":"path","name":"domainId","required":true,"schema":{"format":"uuid","type":"string"}},"FindingId":{"in":"path","name":"findingId","required":true,"schema":{"format":"uuid","type":"string"}},"InstanceId":{"description":"The producer's stable id for this installation.","in":"path","name":"instanceId","required":true,"schema":{"pattern":"^[A-Za-z0-9._:-]{1,100}$","type":"string"}},"Limit":{"in":"query","name":"limit","required":false,"schema":{"default":25,"maximum":100,"minimum":1,"type":"integer"}},"ScanId":{"in":"path","name":"scanId","required":true,"schema":{"format":"uuid","type":"string"}}},"responses":{"Problem":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"An error."}},"schemas":{"ActivityItem":{"properties":{"action":{"description":"e.g. domain.added, domain.verified, authorisation.recorded, scan.started, scan.completed, finding.status_changed.","type":"string"},"actor":{"properties":{"kind":{"enum":["user","staff","system","api_key"],"type":"string"},"label":{"type":"string"}},"required":["kind","label"],"type":"object"},"at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"subject":{"properties":{"id":{"format":"uuid","type":"string"},"kind":{"enum":["domain","scan","finding","assessment","producer"],"type":"string"},"label":{"type":"string"}},"required":["kind","id","label"],"type":"object"},"summary":{"type":"string"}},"required":["id","at","action","actor","summary"],"type":"object"},"AddDomainRequest":{"properties":{"domain":{"examples":["example.co.uk"],"maxLength":300,"type":"string"}},"required":["domain"],"type":"object"},"Assessment":{"properties":{"asset":{"$ref":"#/components/schemas/AssetRef"},"batches_received":{"type":"integer"},"checks":{"properties":{"attempted":{"type":"integer"},"completed":{"type":"integer"},"failed":{"type":"integer"}},"required":["attempted","completed","failed"],"type":"object"},"client_reference":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"description":"While open, when it fails if not completed.","format":"date-time","type":"string"},"findings":{"properties":{"new":{"type":"integer"},"observed":{"type":"integer"},"reopened":{"type":"integer"},"resolved":{"type":"integer"}},"required":["observed","new","reopened","resolved"],"type":"object"},"id":{"format":"uuid","type":"string"},"protocol_version":{"type":"integer"},"results_received":{"type":"integer"},"scan_id":{"description":"The External Security Check this assessment is.","format":"uuid","type":"string"},"source":{"properties":{"instance":{"type":"string"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/SourceType"},"version":{"type":"string"}},"required":["type","name","version"],"type":"object"},"started_at":{"format":"date-time","type":"string"},"status":{"$ref":"#/components/schemas/AssessmentStatus"},"status_reason":{"type":"string"}},"required":["id","asset","source","protocol_version","status","created_at","results_received","batches_received","findings"],"type":"object"},"AssessmentStatus":{"enum":["queued","running","completed","partial","failed","cancelled"],"type":"string"},"AssetRef":{"properties":{"id":{"format":"uuid","type":"string"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/AssetType"}},"required":["id","type","name"],"type":"object"},"AssetReference":{"description":"An asset by id, or by type and name (created with its parents when it does not exist).","properties":{"id":{"format":"uuid","type":"string"},"name":{"maxLength":253,"type":"string"},"parent":{"$ref":"#/components/schemas/AssetReference"},"type":{"$ref":"#/components/schemas/AssetType"}},"type":"object"},"AssetType":{"enum":["domain","hostname","ip_address","service","website","host","virtual_machine","container","container_image","kubernetes_cluster","kubernetes_namespace","cloud_account","wordpress_installation","repository","application","api"],"type":"string"},"Authorisation":{"properties":{"accepted_at":{"format":"date-time","type":"string"},"accepted_by":{"$ref":"#/components/schemas/Person"},"current":{"description":"False when the policy has changed and must be confirmed again.","type":"boolean"},"id":{"format":"uuid","type":"string"},"policy_version":{"type":"string"},"statement":{"type":"string"},"statement_version":{"type":"string"}},"required":["id","policy_version","statement","statement_version","accepted_at","accepted_by","current"],"type":"object"},"AuthoriseRequest":{"properties":{"confirm":{"const":true,"type":"boolean"},"policy_version":{"type":"string"},"statement_version":{"type":"string"}},"required":["policy_version","statement_version","confirm"],"type":"object"},"BatchRequest":{"properties":{"coverage":{"items":{"$ref":"#/components/schemas/Coverage"},"maxItems":2000,"type":"array"},"findings":{"items":{"$ref":"#/components/schemas/SubmittedFinding"},"maxItems":500,"type":"array"},"protocol_version":{"enum":[1],"type":"integer"}},"required":["protocol_version"],"type":"object"},"BatchResponse":{"properties":{"accepted":{"type":"integer"},"assessment":{"properties":{"id":{"format":"uuid","type":"string"},"results_received":{"type":"integer"},"status":{"$ref":"#/components/schemas/AssessmentStatus"}},"required":["id","status","results_received"],"type":"object"},"batch_id":{"type":"string"},"coverage":{"type":"integer"},"duplicates":{"type":"integer"},"new":{"type":"integer"},"rejected":{"items":{"properties":{"field":{"type":"string"},"index":{"type":"integer"},"message":{"type":"string"},"result_id":{"type":"string"}},"required":["index","result_id","field","message"],"type":"object"},"type":"array"},"reopened":{"type":"integer"},"replayed":{"type":"boolean"},"seen":{"type":"integer"},"warnings":{"items":{"properties":{"index":{"type":"integer"},"message":{"type":"string"},"result_id":{"type":"string"}},"required":["index","result_id","message"],"type":"object"},"type":"array"}},"required":["batch_id","replayed","accepted","new","seen","reopened","duplicates","rejected","warnings","coverage","assessment"],"type":"object"},"Capabilities":{"properties":{"assessments":{"description":"Check ids, groups or namespace wildcards this producer can examine.","items":{"type":"string"},"maxItems":200,"type":"array"},"remediations":{"description":"Registered remediation actions this producer can perform.","items":{"type":"string"},"maxItems":200,"type":"array"}},"type":"object"},"CategoryResult":{"properties":{"category":{"$ref":"#/components/schemas/CheckCategory"},"errors":{"type":"integer"},"findings":{"type":"integer"},"passed":{"type":"integer"},"status":{"enum":["pending","running","completed","failed","cancelled"],"type":"string"},"title":{"type":"string"}},"required":["category","title","status","passed","findings","errors"],"type":"object"},"ChangeEvent":{"properties":{"acknowledged":{"description":"Someone has reviewed it. The finding is unchanged.","properties":{"at":{"format":"date-time","type":"string"},"by":{"type":"string"}},"required":["by","at"],"type":"object"},"details":{"additionalProperties":true,"description":"Before and after where a change has them: a replaced certificate's issuer, names and expiry; a record's values. Expiry warnings carry `milestone`, `not_after`, `seen_at` and, when Ironfang could not look again before warning, `confirmed: false`.","type":"object"},"domain":{"type":"string"},"domain_id":{"format":"uuid","type":"string"},"finding_id":{"format":"uuid","type":"string"},"group":{"$ref":"#/components/schemas/ChangeGroup"},"host":{"type":"string"},"id":{"format":"uuid","type":"string"},"occurred_at":{"format":"date-time","type":"string"},"previous_scan_id":{"description":"The scan it was compared with.","format":"uuid","type":"string"},"scan_id":{"description":"The scan that found it. Absent for expiry warnings between scans.","format":"uuid","type":"string"},"severity":{"$ref":"#/components/schemas/Severity"},"summary":{"description":"Plain English, safe to show as is.","type":"string"},"title":{"type":"string"},"type":{"$ref":"#/components/schemas/ChangeType"}},"required":["id","type","group","severity","title","summary","domain_id","domain","details","occurred_at"],"type":"object"},"ChangeGroup":{"description":"The Changes feed's filters.","enum":["new","resolved","exposure","certificates","dns","monitoring"],"type":"string"},"ChangeType":{"enum":["finding_new","finding_resolved","finding_recurred","finding_severity_increased","finding_severity_decreased","service_exposed","service_removed","certificate_changed","certificate_expiring","certificate_expired","tls_configuration_weakened","tls_configuration_improved","dns_record_changed","dns_security_weakened","dns_security_improved","spf_changed","dmarc_changed","email_security_weakened","email_security_improved","http_security_weakened","http_security_improved","monitoring_scan_failed","monitoring_scan_recovered","monitoring_paused"],"type":"string"},"ChannelPreference":{"allOf":[{"$ref":"#/components/schemas/NotificationPreference"},{"properties":{"custom":{"description":"False while the recommended set applies.","type":"boolean"}},"required":["custom"],"type":"object"}]},"CheckCategory":{"description":"The External Security Check's check families.","enum":["dns","tls","http","email","exposure","technology","discovery"],"type":"string"},"CheckNote":{"properties":{"check_id":{"type":"string"},"host":{"type":"string"},"message":{"type":"string"},"title":{"type":"string"}},"required":["check_id","title","host","message"],"type":"object"},"Classification":{"properties":{"id":{"description":"e.g. CVE-2026-12345, CWE-79, A05:2021, 1.1.1.","type":"string"},"scheme":{"$ref":"#/components/schemas/ClassificationScheme"}},"required":["scheme","id"],"type":"object"},"ClassificationScheme":{"enum":["cve","cwe","ghsa","osv","owasp_top10","owasp_asvs","capec","mitre_attack","cis","nist_800_53","nist_csf","cyber_essentials","iso27001","pci_dss"],"type":"string"},"CompleteAssessmentRequest":{"properties":{"checks":{"properties":{"attempted":{"minimum":0,"type":"integer"},"completed":{"minimum":0,"type":"integer"},"failed":{"minimum":0,"type":"integer"}},"required":["attempted","completed","failed"],"type":"object"},"coverage":{"items":{"$ref":"#/components/schemas/Coverage"},"maxItems":2000,"type":"array"},"protocol_version":{"enum":[1],"type":"integer"},"reason":{"maxLength":500,"type":"string"},"status":{"enum":["completed","partial","failed","cancelled"],"type":"string"}},"required":["protocol_version","status"],"type":"object"},"Confidence":{"description":"How sure Ironfang is. `low` is presented as \"potential\".","enum":["confirmed","high","medium","low"],"type":"string"},"Coverage":{"properties":{"check":{"description":"A check id, a check group, or a namespace wildcard such as ironfang.wordpress.plugin.*.","type":"string"},"outcome":{"enum":["completed","failed","skipped"],"type":"string"},"resource":{"description":"Omitted for the whole asset.","properties":{"identifier":{"type":"string"},"type":{"type":"string"}},"required":["type","identifier"],"type":"object"}},"required":["check","outcome"],"type":"object"},"Cvss":{"properties":{"base_score":{"maximum":10,"minimum":0,"type":"number"},"vector":{"type":"string"},"version":{"enum":["2.0","3.0","3.1","4.0"],"type":"string"}},"required":["version","base_score"],"type":"object"},"Discovery":{"properties":{"first_seen_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"in_scope":{"description":"Always false in V1; discoveries are never scanned automatically.","type":"boolean"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"source":{"enum":["certificate_transparency"],"type":"string"}},"required":["id","name","source","first_seen_at","last_seen_at","in_scope"],"type":"object"},"DnsProvider":{"properties":{"help_url":{"format":"uri","type":"string"},"id":{"description":"e.g. cloudflare, route53, godaddy, namecheap, azure, google, other","type":"string"},"name":{"type":"string"}},"required":["id","name"],"type":"object"},"Domain":{"allOf":[{"$ref":"#/components/schemas/DomainSummary"},{"properties":{"authorisation":{"$ref":"#/components/schemas/Authorisation"},"discoveries":{"description":"Number of discovered names.","type":"integer"},"verification":{"$ref":"#/components/schemas/Verification"}},"required":["verification","discoveries"],"type":"object"}]},"DomainSummary":{"properties":{"authorised":{"type":"boolean"},"can_scan":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"id":{"format":"uuid","type":"string"},"latest_scan":{"$ref":"#/components/schemas/ScanSummary"},"monitoring":{"$ref":"#/components/schemas/MonitoringBrief"},"name":{"description":"ASCII (punycode) name.","type":"string"},"next_scan_at":{"description":"When the cooldown ends.","format":"date-time","type":"string"},"open_findings":{"$ref":"#/components/schemas/SeverityCounts"},"scan_blocked_reason":{"$ref":"#/components/schemas/ScanBlockedReason"},"verification_status":{"$ref":"#/components/schemas/VerificationStatus"}},"required":["id","name","display_name","verification_status","authorised","can_scan","open_findings","created_at"],"type":"object"},"Evidence":{"properties":{"assessment_id":{"format":"uuid","type":"string"},"captured_at":{"format":"date-time","type":"string"},"content_type":{"type":"string"},"data":{"description":"The captured value, structured or text; null unless inline."},"id":{"format":"uuid","type":"string"},"kind":{"$ref":"#/components/schemas/EvidenceKind"},"label":{"type":"string"},"redactions":{"description":"Kinds of secret removed before it was stored.","items":{"type":"string"},"type":"array"},"scan_id":{"format":"uuid","type":"string"},"sensitivity":{"$ref":"#/components/schemas/Sensitivity"},"sha256":{"type":"string"},"size_bytes":{"type":"integer"},"storage":{"description":"inline is stored; local is kept by the producer and withheld was too sensitive to keep (data is null, sha256 proves what was seen).","enum":["inline","local","withheld"],"type":"string"},"summary":{"deprecated":true,"description":"label.","type":"string"}},"required":["id","kind","summary","label","sensitivity","storage","data","sha256","size_bytes","captured_at","assessment_id"],"type":"object"},"EvidenceKind":{"enum":["dns_answer","certificate","tls_handshake","http_response","tcp_connect","service_banner","certificate_transparency","note","http_request","http_headers","file","configuration","package","software_version","kubernetes_object","command_output","matcher","native_result","screenshot"],"type":"string"},"Finding":{"allOf":[{"$ref":"#/components/schemas/FindingSummary"},{"properties":{"check":{"properties":{"category":{"$ref":"#/components/schemas/FindingCategory"},"group":{"description":"What the producer ran (the External Security Check's catalogue check).","properties":{"id":{"type":"string"},"title":{"type":"string"}},"required":["id"],"type":"object"},"id":{"type":"string"},"subcategory":{"type":"string"},"title":{"type":"string"},"version":{"type":"string"}},"required":["id","version","category","title"],"type":"object"},"classifications":{"items":{"$ref":"#/components/schemas/Classification"},"type":"array"},"cvss":{"$ref":"#/components/schemas/Cvss"},"cwe":{"deprecated":true,"description":"The first cwe classification.","type":"string"},"description":{"type":"string"},"docs_url":{"format":"uri","type":"string"},"evidence":{"items":{"$ref":"#/components/schemas/Evidence"},"type":"array"},"fingerprint":{"description":"SHA-256 of the finding's identity (docs: the Ironfang Finding Format).","type":"string"},"fix":{"deprecated":true,"description":"remediation.guidance.","type":"string"},"history":{"items":{"$ref":"#/components/schemas/FindingEvent"},"type":"array"},"impact":{"description":"Why it matters.","type":"string"},"note":{"description":"The latest note recorded with a status change.","type":"string"},"observations":{"description":"The latest sightings, newest first.","items":{"$ref":"#/components/schemas/Observation"},"type":"array"},"recheck":{"$ref":"#/components/schemas/Recheck"},"references":{"items":{"format":"uri","type":"string"},"type":"array"},"related":{"items":{"$ref":"#/components/schemas/RelatedFinding"},"type":"array"},"remediation":{"$ref":"#/components/schemas/Remediation"},"summary":{"description":"What this kind of issue is.","type":"string"},"why":{"deprecated":true,"description":"impact.","type":"string"}},"required":["fingerprint","check","summary","why","fix","remediation","references","classifications","evidence","observations","related","history","recheck"],"type":"object"}]},"FindingCategory":{"description":"The area a finding is in; the first seven are the External Security Check's.","enum":["dns","tls","http","email","exposure","technology","discovery","configuration","vulnerability","access_control","authentication","secrets","network","logging","malware","data_protection","other"],"type":"string"},"FindingEvent":{"properties":{"actor":{"$ref":"#/components/schemas/Person"},"at":{"format":"date-time","type":"string"},"confidence":{"$ref":"#/components/schemas/Confidence"},"from_confidence":{"$ref":"#/components/schemas/Confidence"},"from_severity":{"$ref":"#/components/schemas/Severity"},"from_status":{"$ref":"#/components/schemas/FindingStatus"},"kind":{"description":"reopened is a finding that was resolved and came back (the same issue, recurring). severity_changed and confidence_changed are recorded by the scan that saw the change. identity_merged marks findings for one port on different addresses combined into one.","enum":["detected","seen","status_changed","recheck_requested","recheck_resolved","recheck_still_present","resolved","reopened","severity_changed","confidence_changed","identity_merged"],"type":"string"},"note":{"type":"string"},"scan_id":{"format":"uuid","type":"string"},"severity":{"$ref":"#/components/schemas/Severity"},"to_status":{"$ref":"#/components/schemas/FindingStatus"}},"required":["at","kind"],"type":"object"},"FindingKind":{"enum":["issue","hardening","informational","potential_vulnerability"],"type":"string"},"FindingStatus":{"description":"open and in_progress still ask something of you. resolved is no longer present. accepted is real with the risk accepted; suppressed is hidden without a judgement; false_positive is not real.","enum":["open","in_progress","resolved","accepted","suppressed","false_positive"],"type":"string"},"FindingSummary":{"properties":{"asset":{"$ref":"#/components/schemas/AssetRef"},"category":{"$ref":"#/components/schemas/FindingCategory"},"check_id":{"description":"Canonical, namespaced and permanent, e.g. ironfang.http.hsts_missing.","type":"string"},"confidence":{"$ref":"#/components/schemas/Confidence"},"detail":{"description":"What was observed in this instance.","type":"string"},"domain_id":{"deprecated":true,"description":"asset.id.","format":"uuid","type":"string"},"first_seen_at":{"format":"date-time","type":"string"},"host":{"deprecated":true,"description":"resource.identifier.","type":"string"},"id":{"format":"uuid","type":"string"},"key":{"deprecated":true,"description":"The producer's own key (the catalogue key, e.g. http.hsts_missing, for the External Security Check). Use check_id.","type":"string"},"kind":{"$ref":"#/components/schemas/FindingKind"},"last_seen_at":{"format":"date-time","type":"string"},"resolved_at":{"format":"date-time","type":"string"},"resource":{"$ref":"#/components/schemas/Resource"},"severity":{"$ref":"#/components/schemas/Severity"},"source":{"$ref":"#/components/schemas/Source"},"status":{"$ref":"#/components/schemas/FindingStatus"},"title":{"type":"string"},"verification":{"description":"Whether an assessment has confirmed the current state.","enum":["unverified","fixed_verified","still_present"],"type":"string"}},"required":["id","check_id","key","title","category","kind","severity","confidence","status","source","asset","resource","host","domain_id","first_seen_at","last_seen_at","verification"],"type":"object"},"Limits":{"properties":{"full_scan_cooldown_seconds":{"type":"integer"},"manual_verification_interval_seconds":{"type":"integer"},"max_concurrent_scans":{"type":"integer"},"max_domains":{"type":"integer"},"max_monitored_domains":{"description":"Monitored domains per organisation during the preview.","type":"integer"},"max_pending_verifications":{"type":"integer"},"max_scans_per_day":{"type":"integer"},"monitoring_daily_allowed":{"type":"boolean"},"monitoring_pause_after_failures":{"description":"Scheduled checks in a row that may fail before monitoring pauses.","type":"integer"},"recheck_cooldown_seconds":{"type":"integer"},"verification_ttl_seconds":{"type":"integer"}},"required":["max_domains","max_pending_verifications","full_scan_cooldown_seconds","max_scans_per_day","max_concurrent_scans","recheck_cooldown_seconds","manual_verification_interval_seconds","verification_ttl_seconds"],"type":"object"},"Monitoring":{"properties":{"available":{"description":"Whether monitoring can be switched on or changed now.","type":"boolean"},"consecutive_failures":{"type":"integer"},"domain":{"type":"string"},"domain_id":{"format":"uuid","type":"string"},"frequencies":{"description":"The frequencies this organisation may choose.","items":{"$ref":"#/components/schemas/MonitoringFrequency"},"type":"array"},"frequency":{"allOf":[{"$ref":"#/components/schemas/MonitoringFrequency"}],"nullable":true},"health":{"$ref":"#/components/schemas/MonitoringHealth"},"last_completed_at":{"format":"date-time","nullable":true,"type":"string"},"last_scheduled_at":{"format":"date-time","nullable":true,"type":"string"},"last_successful_scan_id":{"format":"uuid","nullable":true,"type":"string"},"next_run_at":{"format":"date-time","nullable":true,"type":"string"},"schedule":{"description":"When checks run, e.g. \"Tuesdays around 03:17 UTC\".","nullable":true,"type":"string"},"state":{"$ref":"#/components/schemas/MonitoringState"},"state_reason":{"description":"Why monitoring is paused, in words the customer can act on.","nullable":true,"type":"string"},"unavailable_reason":{"nullable":true,"type":"string"},"usage":{"properties":{"max":{"type":"integer"},"used":{"type":"integer"}},"required":["used","max"],"type":"object"}},"required":["domain_id","domain","state","health","consecutive_failures","available","frequencies","usage"],"type":"object"},"MonitoringBrief":{"properties":{"frequency":{"$ref":"#/components/schemas/MonitoringFrequency"},"health":{"$ref":"#/components/schemas/MonitoringHealth"},"next_run_at":{"format":"date-time","type":"string"},"state":{"$ref":"#/components/schemas/MonitoringState"}},"required":["state","health","frequency"],"type":"object"},"MonitoringFrequency":{"enum":["daily","weekly"],"type":"string"},"MonitoringHealth":{"description":"healthy; delayed (a scheduled check is waiting on Ironfang's capacity); attention (recent scheduled checks could not complete); paused; off.","enum":["healthy","delayed","attention","paused","off"],"type":"string"},"MonitoringState":{"description":"off (never switched on, or switched off), pending_first_run, active, paused (by the customer), paused_verification_lost, paused_authorisation, paused_repeated_failures, paused_by_ironfang.","enum":["off","pending_first_run","active","paused","paused_verification_lost","paused_authorisation","paused_repeated_failures","paused_by_ironfang"],"type":"string"},"NotificationPreference":{"properties":{"certificate_alerts":{"description":"Replaced certificates and expiry milestones.","type":"boolean"},"dns_changes":{"description":"DNS and email records.","type":"boolean"},"enabled":{"type":"boolean"},"exposure_changes":{"type":"boolean"},"minimum_severity":{"$ref":"#/components/schemas/Severity"},"monitoring_failures":{"description":"Scheduled checks that could not complete, and pauses.","type":"boolean"},"new_findings":{"description":"New issues, returns and severity increases.","type":"boolean"},"resolved_findings":{"description":"Resolved issues and improvements.","type":"boolean"}},"required":["enabled","minimum_severity","new_findings","resolved_findings","exposure_changes","certificate_alerts","dns_changes","monitoring_failures"],"type":"object"},"NotificationPreferences":{"properties":{"email":{"$ref":"#/components/schemas/ChannelPreference"},"in_app":{"$ref":"#/components/schemas/ChannelPreference"}},"required":["in_app","email"],"type":"object"},"Observation":{"description":"One sighting, with the producer's own record of it.","properties":{"assessment_id":{"format":"uuid","type":"string"},"detail":{"type":"string"},"id":{"format":"uuid","type":"string"},"native":{"additionalProperties":true,"type":"object"},"native_check_id":{"type":"string"},"observed_at":{"format":"date-time","type":"string"},"result_id":{"type":"string"}},"required":["id","assessment_id","observed_at","native_check_id"],"type":"object"},"Overview":{"properties":{"domains":{"items":{"$ref":"#/components/schemas/DomainSummary"},"type":"array"},"latest_scan":{"$ref":"#/components/schemas/ScanSummary"},"limits":{"$ref":"#/components/schemas/Limits"},"message":{"type":"string"},"open_findings":{"$ref":"#/components/schemas/SeverityCounts"},"recent_activity":{"items":{"$ref":"#/components/schemas/ActivityItem"},"type":"array"},"recommended_actions":{"items":{"$ref":"#/components/schemas/RecommendedAction"},"type":"array"},"state":{"enum":["enabled","scans_paused","disabled"],"type":"string"}},"required":["state","domains","open_findings","recommended_actions","recent_activity","limits"],"type":"object"},"PassedCheck":{"properties":{"category":{"$ref":"#/components/schemas/CheckCategory"},"check_id":{"type":"string"},"docs_url":{"format":"uri","type":"string"},"host":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"required":["check_id","title","category","host","summary","docs_url"],"type":"object"},"Person":{"properties":{"label":{"type":"string"}},"required":["label"],"type":"object"},"PolicyItem":{"properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}},"required":["id","title","description"],"type":"object"},"Problem":{"properties":{"error":{"properties":{"code":{"description":"Stable error code. Among them: `unauthorized`, `forbidden`,\n`not_found`, `validation_failed`, `domain_invalid`,\n`domain_exists`, `domain_limit_reached`,\n`verification_pending_limit`, `verification_required`,\n`already_verified`, `authorisation_required`,\n`policy_outdated`, `scan_in_progress`, `scan_cooldown`,\n`daily_limit_reached`, `domain_rate_limited`, `scan_not_active`,\n`recheck_unavailable`, `recheck_cooldown`, `check_rate_limited`,\n`organisation_suspended`, `scans_paused`, `security_disabled`,\n`verification_expired`, `verification_unavailable`,\n`verification_pending_limit`, `finding_resolved`, `internal`.\nSubmitting assessments: `unsupported_protocol_version`,\n`invalid_json`, `invalid_api_key`, `batch_conflict`,\n`assessment_closed`, `assessment_expired`,\n`assessment_managed`, `asset_archived`, `asset_limit`,\n`producer_limit`, `too_many_open_assessments`.\nFrom the Ironfang API in front of the service:\n`api_keys_not_supported`, `permissions_unavailable`,\n`body_too_large`, `invalid_body`, `invalid_tenant`,\n`security_unavailable`, `security_timeout`.\n","type":"string"},"docs":{"format":"uri","type":"string"},"message":{"type":"string"},"retry_after_seconds":{"description":"Set on cooldowns and rate limits.","type":"integer"}},"required":["code","message"],"type":"object"},"request_id":{"type":"string"}},"required":["error","request_id"],"type":"object"},"Producer":{"properties":{"asset":{"$ref":"#/components/schemas/AssetRef"},"capabilities":{"$ref":"#/components/schemas/Capabilities"},"first_seen_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"instance_id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"protocol_version":{"type":"integer"},"type":{"$ref":"#/components/schemas/SourceType"},"version":{"type":"string"}},"required":["id","instance_id","type","name","version","protocol_version","capabilities","first_seen_at","last_seen_at"],"type":"object"},"ProducerRegistration":{"properties":{"ignored":{"properties":{"remediations":{"description":"Actions this server does not know.","items":{"type":"string"},"type":"array"}},"required":["remediations"],"type":"object"},"producer":{"$ref":"#/components/schemas/Producer"}},"required":["producer","ignored"],"type":"object"},"Protocol":{"properties":{"asset_types":{"items":{"type":"string"},"type":"array"},"categories":{"items":{"type":"string"},"type":"array"},"classification_schemes":{"items":{"type":"string"},"type":"array"},"current":{"type":"integer"},"evidence_kinds":{"items":{"type":"string"},"type":"array"},"finding_statuses":{"items":{"type":"string"},"type":"array"},"fingerprint":{"description":"The first line of every fingerprint's input.","type":"string"},"limits":{"additionalProperties":{"type":"integer"},"type":"object"},"protocol_versions":{"items":{"type":"integer"},"type":"array"},"remediation_actions":{"items":{"$ref":"#/components/schemas/RemediationAction"},"type":"array"},"sensitivities":{"items":{"type":"string"},"type":"array"},"source_types":{"items":{"properties":{"auto_resolves":{"type":"boolean"},"ironfang_namespace":{"type":"boolean"},"manually_resolvable":{"type":"boolean"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/SourceType"}},"required":["type","name","ironfang_namespace","auto_resolves","manually_resolvable"],"type":"object"},"type":"array"}},"required":["protocol_versions","current","fingerprint","limits","source_types","asset_types","categories","classification_schemes","evidence_kinds","sensitivities","finding_statuses","remediation_actions"],"type":"object"},"Recheck":{"properties":{"available":{"type":"boolean"},"available_at":{"format":"date-time","type":"string"},"reason":{"description":"Why a recheck cannot start now.","type":"string"},"scan_id":{"description":"The recheck in progress.","format":"uuid","type":"string"}},"required":["available"],"type":"object"},"RecommendedAction":{"properties":{"confidence":{"$ref":"#/components/schemas/Confidence"},"domain_id":{"format":"uuid","type":"string"},"finding_id":{"format":"uuid","type":"string"},"host":{"type":"string"},"reason":{"type":"string"},"severity":{"$ref":"#/components/schemas/Severity"},"title":{"type":"string"}},"required":["finding_id","title","severity","confidence","host","domain_id","reason"],"type":"object"},"RegisterProducerRequest":{"properties":{"asset":{"$ref":"#/components/schemas/AssetReference"},"capabilities":{"$ref":"#/components/schemas/Capabilities"},"name":{"maxLength":100,"type":"string"},"protocol_version":{"enum":[1],"type":"integer"},"type":{"$ref":"#/components/schemas/SourceType"},"version":{"maxLength":50,"type":"string"}},"required":["protocol_version","type","version"],"type":"object"},"RelatedFinding":{"properties":{"check_id":{"type":"string"},"id":{"format":"uuid","type":"string"},"kind":{"enum":["related_to","duplicate_of","caused_by","parent_of"],"type":"string"},"reason":{"type":"string"},"source_type":{"$ref":"#/components/schemas/SourceType"},"status":{"$ref":"#/components/schemas/FindingStatus"},"title":{"type":"string"}},"required":["id","kind","check_id","title","source_type","status"],"type":"object"},"Remediation":{"properties":{"action":{"$ref":"#/components/schemas/RemediationAction"},"guidance":{"description":"What a person should do. May contain inline `code`.","type":"string"}},"type":"object"},"RemediationAction":{"properties":{"available":{"description":"A producer attached to the finding's asset advertises this action and was seen in the last seven days.","type":"boolean"},"description":{"type":"string"},"id":{"description":"e.g. wordpress.update_plugin.","type":"string"},"parameters":{"oneOf":[{"additionalProperties":{"type":"string"},"description":"On a finding, the values this finding gives the action.","type":"object"},{"description":"In the registry, the parameter names the action takes.","items":{"type":"string"},"type":"array"}]},"requires_confirmation":{"type":"boolean"},"restart":{"enum":["none","service","workload","host"],"type":"string"},"reversible":{"type":"boolean"},"risk":{"enum":["low","medium","high"],"type":"string"},"title":{"type":"string"}},"required":["id","title","description","risk","requires_confirmation","reversible","restart"],"type":"object"},"Resource":{"properties":{"identifier":{"type":"string"},"identity":{"additionalProperties":{"type":"string"},"description":"What tells two instances of one check on one resource apart (a port, a cookie name).","type":"object"},"type":{"description":"host, file, wordpress_plugin, kubernetes_container, ... or asset (the asset itself).","type":"string"}},"required":["type","identifier"],"type":"object"},"Scan":{"allOf":[{"$ref":"#/components/schemas/ScanSummary"},{"properties":{"categories":{"items":{"$ref":"#/components/schemas/CategoryResult"},"type":"array"},"disclaimer":{"type":"string"},"errors":{"description":"Checks that could not complete.","items":{"$ref":"#/components/schemas/CheckNote"},"type":"array"},"findings":{"description":"Findings observed in this scan.","items":{"$ref":"#/components/schemas/FindingSummary"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"observations":{"description":"Informational results that are neither a pass nor a finding (e.g. detected technologies).","items":{"$ref":"#/components/schemas/CheckNote"},"type":"array"},"passed_checks":{"items":{"$ref":"#/components/schemas/PassedCheck"},"type":"array"},"policy_version":{"type":"string"},"previous_scan_id":{"description":"The domain's previous full scan, to compare with.","format":"uuid","type":"string"},"recommended_actions":{"items":{"$ref":"#/components/schemas/RecommendedAction"},"type":"array"},"requested_by":{"$ref":"#/components/schemas/Person"},"scanner":{"$ref":"#/components/schemas/ScannerIdentity"}},"required":["policy_version","categories","findings","passed_checks","observations","errors","limitations","recommended_actions","scanner","disclaimer"],"type":"object"}]},"ScanBlockedReason":{"description":"Why a scan cannot start now.","enum":["verification_required","authorisation_required","policy_outdated","scan_in_progress","scan_cooldown","daily_limit_reached","organisation_suspended","scans_paused","security_disabled"],"type":"string"},"ScanChanges":{"properties":{"fixed":{"type":"integer"},"new":{"type":"integer"},"reopened":{"type":"integer"}},"required":["new","fixed","reopened"],"type":"object"},"ScanComparison":{"properties":{"categories":{"description":"Categories completed in both scans, the only ones compared.","items":{"$ref":"#/components/schemas/CheckCategory"},"type":"array"},"new":{"description":"Failing in the later scan and not the earlier one.","items":{"$ref":"#/components/schemas/FindingSummary"},"type":"array"},"previous":{"$ref":"#/components/schemas/ScanSummary"},"resolved":{"description":"Failing in the earlier scan and not the later one.","items":{"$ref":"#/components/schemas/FindingSummary"},"type":"array"},"returned":{"description":"Among `new`, findings seen before the earlier scan that came back.","items":{"format":"uuid","type":"string"},"type":"array"},"scan":{"$ref":"#/components/schemas/ScanSummary"},"severity_changed":{"items":{"properties":{"finding":{"$ref":"#/components/schemas/FindingSummary"},"from":{"$ref":"#/components/schemas/Severity"},"to":{"$ref":"#/components/schemas/Severity"}},"required":["finding","from","to"],"type":"object"},"type":"array"},"unchanged":{"description":"Findings failing in both.","type":"integer"}},"required":["scan","previous","categories","new","returned","resolved","severity_changed","unchanged"],"type":"object"},"ScanCounts":{"properties":{"confirmed":{"description":"Findings with confirmed or high confidence.","type":"integer"},"critical":{"type":"integer"},"errors":{"description":"Checks that could not complete.","type":"integer"},"high":{"type":"integer"},"info":{"type":"integer"},"low":{"type":"integer"},"medium":{"type":"integer"},"passed":{"description":"Checks that observed a control working.","type":"integer"},"unverified":{"description":"Findings with medium or low confidence.","type":"integer"}},"required":["critical","high","medium","low","info","passed","confirmed","unverified","errors"],"type":"object"},"ScanKind":{"description":"`certificate` is monitoring looking at one host's certificate again before warning that it is about to expire.","enum":["full","recheck","certificate"],"type":"string"},"ScanPolicy":{"properties":{"disclaimer":{"type":"string"},"excluded":{"items":{"$ref":"#/components/schemas/PolicyItem"},"type":"array"},"included":{"items":{"$ref":"#/components/schemas/PolicyItem"},"type":"array"},"scanner":{"$ref":"#/components/schemas/ScannerIdentity"},"statement":{"type":"string"},"statement_version":{"type":"string"},"summary":{"type":"string"},"terms_url":{"format":"uri","type":"string"},"title":{"type":"string"},"version":{"type":"string"}},"required":["version","title","summary","included","excluded","statement","statement_version","terms_url","scanner","disclaimer"],"type":"object"},"ScanStatus":{"enum":["queued","running","completed","partial","failed","cancelled","killed"],"type":"string"},"ScanSummary":{"properties":{"changes":{"$ref":"#/components/schemas/ScanChanges"},"counts":{"$ref":"#/components/schemas/ScanCounts"},"domain":{"type":"string"},"domain_id":{"format":"uuid","type":"string"},"duration_ms":{"type":"integer"},"failure_class":{"description":"For a failed scan, whose problem it was — the domain did not answer, or Ironfang could not run it.","enum":["asset","ironfang"],"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"kind":{"$ref":"#/components/schemas/ScanKind"},"progress":{"properties":{"completed":{"type":"integer"},"total":{"type":"integer"}},"required":["total","completed"],"type":"object"},"recheck_finding_id":{"format":"uuid","type":"string"},"requested_at":{"format":"date-time","type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"$ref":"#/components/schemas/ScanStatus"},"status_reason":{"description":"Why a scan was cancelled, stopped or failed.","type":"string"},"trigger":{"$ref":"#/components/schemas/ScanTrigger"}},"required":["id","domain_id","domain","kind","trigger","status","requested_at","progress","counts"],"type":"object"},"ScanTrigger":{"description":"Why a scan ran.","enum":["manual","recheck","monitoring","admin","api"],"type":"string"},"ScannerIdentity":{"properties":{"info_url":{"format":"uri","type":"string"},"source_addresses":{"description":"Public addresses scanner traffic comes from, for allowlisting.","items":{"type":"string"},"type":"array"},"user_agent":{"type":"string"}},"required":["user_agent","info_url","source_addresses"],"type":"object"},"Sensitivity":{"description":"public is what the internet sees; restricted is never stored.","enum":["public","internal","confidential","restricted"],"type":"string"},"ServiceStatus":{"properties":{"features":{"description":"What this build offers the caller, so a client shows only what exists. Absent from builds before monitoring.","properties":{"changes":{"description":"The Changes feed exists.","type":"boolean"},"monitoring":{"description":"Scheduled checks can be offered to this caller.","type":"boolean"},"notifications":{"description":"Notification preferences and acknowledging changes exist.","type":"boolean"}},"required":["monitoring","changes"],"type":"object"},"limits":{"$ref":"#/components/schemas/Limits"},"message":{"description":"Shown to customers while paused or disabled.","type":"string"},"preview":{"description":"True while Security is a free preview.","type":"boolean"},"scanner":{"$ref":"#/components/schemas/ScannerIdentity"},"state":{"enum":["enabled","scans_paused","disabled"],"type":"string"}},"required":["state","preview","limits","scanner"],"type":"object"},"Severity":{"enum":["critical","high","medium","low","info"],"type":"string"},"SeverityCounts":{"properties":{"critical":{"type":"integer"},"high":{"type":"integer"},"info":{"type":"integer"},"low":{"type":"integer"},"medium":{"type":"integer"}},"required":["critical","high","medium","low","info"],"type":"object"},"Source":{"properties":{"name":{"type":"string"},"native_severity":{"description":"The producer's own severity, before normalisation.","type":"string"},"type":{"$ref":"#/components/schemas/SourceType"}},"required":["type","name"],"type":"object"},"SourceReference":{"properties":{"instance":{"description":"The registered producer's instance id.","pattern":"^[A-Za-z0-9._:-]{1,100}$","type":"string"},"name":{"maxLength":100,"type":"string"},"type":{"$ref":"#/components/schemas/SourceType"},"version":{"description":"The producer's release version, unrelated to the protocol's.","maxLength":50,"type":"string"}},"required":["type","version"],"type":"object"},"SourceType":{"description":"What kind of producer a result came from. external_scan is the External Security Check and cannot be submitted.","enum":["external_scan","wordpress_agent","linux_agent","kubernetes_agent","container_scanner","cloud_integration","dependency_scanner","ai_assessment","nuclei","import","manual"],"type":"string"},"StartAssessmentRequest":{"properties":{"asset":{"$ref":"#/components/schemas/AssetReference"},"client_reference":{"description":"The producer's id for this run; use a UUID.","pattern":"^[A-Za-z0-9._:-]{1,100}$","type":"string"},"protocol_version":{"enum":[1],"type":"integer"},"source":{"$ref":"#/components/schemas/SourceReference"},"started_at":{"format":"date-time","type":"string"}},"required":["protocol_version","source","asset"],"type":"object"},"SubmittedEvidence":{"properties":{"captured_at":{"format":"date-time","type":"string"},"content_type":{"maxLength":100,"type":"string"},"data":{"description":"Structured value, at most 64 KiB and 8 deep. Exactly one of data and text for inline evidence."},"kind":{"$ref":"#/components/schemas/EvidenceKind"},"label":{"maxLength":200,"type":"string"},"sensitivity":{"$ref":"#/components/schemas/Sensitivity"},"sha256":{"description":"Required for local evidence.","pattern":"^[0-9a-fA-F]{64}$","type":"string"},"size_bytes":{"type":"integer"},"storage":{"default":"inline","enum":["inline","local"],"type":"string"},"text":{"type":"string"}},"required":["kind","label"],"type":"object"},"SubmittedFinding":{"properties":{"check":{"properties":{"category":{"$ref":"#/components/schemas/FindingCategory"},"group":{"maxLength":200,"type":"string"},"id":{"description":"Namespaced and permanent; the ironfang. namespace is for Ironfang's own producers.","maxLength":200,"type":"string"},"subcategory":{"pattern":"^[a-z][a-z0-9_]{0,39}$","type":"string"},"title":{"maxLength":200,"type":"string"},"version":{"maxLength":20,"type":"string"}},"required":["id","category","title"],"type":"object"},"classifications":{"items":{"$ref":"#/components/schemas/Classification"},"maxItems":32,"type":"array"},"confidence":{"$ref":"#/components/schemas/Confidence"},"cvss":{"$ref":"#/components/schemas/Cvss"},"description":{"maxLength":8000,"type":"string"},"detail":{"maxLength":2000,"type":"string"},"evidence":{"items":{"$ref":"#/components/schemas/SubmittedEvidence"},"maxItems":10,"type":"array"},"identity":{"additionalProperties":{"maxLength":256,"type":"string"},"maxProperties":8,"type":"object"},"impact":{"maxLength":4000,"type":"string"},"kind":{"$ref":"#/components/schemas/FindingKind"},"native":{"properties":{"check_id":{"type":"string"},"metadata":{"additionalProperties":true,"description":"At most 8 KiB.","type":"object"},"severity":{"type":"string"},"version":{"type":"string"}},"type":"object"},"observed_at":{"format":"date-time","type":"string"},"references":{"items":{"format":"uri","type":"string"},"maxItems":20,"type":"array"},"remediation":{"properties":{"action":{"type":"string"},"guidance":{"maxLength":4000,"type":"string"},"parameters":{"additionalProperties":{"type":"string"},"type":"object"}},"type":"object"},"resource":{"properties":{"identifier":{"maxLength":512,"type":"string"},"type":{"pattern":"^[a-z][a-z0-9_]{0,39}$","type":"string"}},"required":["type","identifier"],"type":"object"},"result_id":{"description":"Unique within the assessment.","pattern":"^[A-Za-z0-9._:-]{1,100}$","type":"string"},"severity":{"$ref":"#/components/schemas/Severity"},"summary":{"description":"Required.","maxLength":1000,"type":"string"}},"required":["result_id","check","severity","confidence"],"type":"object"},"UpdateFindingRequest":{"properties":{"note":{"maxLength":1000,"type":"string"},"status":{"description":"resolved only on manual and imported findings. The names used before 0.2.0 (acknowledged, accepted_risk) are accepted for one release.","enum":["open","in_progress","accepted","suppressed","false_positive","resolved"],"type":"string"}},"required":["status"],"type":"object"},"Verification":{"properties":{"checks":{"description":"How many times the record has been looked up.","type":"integer"},"dns_provider":{"$ref":"#/components/schemas/DnsProvider"},"expires_at":{"format":"date-time","type":"string"},"failure_reason":{"type":"string"},"last_checked_at":{"format":"date-time","type":"string"},"manual_check_available_at":{"format":"date-time","type":"string"},"method":{"enum":["dns_txt"],"type":"string"},"next_check_at":{"format":"date-time","type":"string"},"observed_values":{"description":"TXT values seen at the record name on the last lookup, to help troubleshooting.","items":{"type":"string"},"type":"array"},"record":{"$ref":"#/components/schemas/VerificationRecord"},"status":{"$ref":"#/components/schemas/VerificationStatus"},"verified_at":{"format":"date-time","type":"string"}},"required":["status","method","record","checks"],"type":"object"},"VerificationRecord":{"properties":{"host_label":{"description":"The name relative to the domain, for providers that append the domain.","type":"string"},"name":{"description":"Fully qualified record name.","type":"string"},"type":{"enum":["TXT"],"type":"string"},"value":{"type":"string"}},"required":["type","name","host_label","value"],"type":"object"},"VerificationStatus":{"enum":["waiting","checking","verified","failed","expired","lapsed"],"type":"string"}},"securitySchemes":{"bearerAuth":{"bearerFormat":"Warden JWT","description":"A Warden user token. Each route also requires a tenant permission in\nthe acting tenant (`X-Ironfang-Tenant`), resolved live from Warden:\nreads need `security.read`; everything that changes state needs\n`security.write`; assessments and producers need\n`security.assessments.write`. A missing permission is 403; a\npermission lookup failure is 503.\n","scheme":"bearer","type":"http"},"platformApiKey":{"bearerFormat":"if_live_ platform API key","description":"A platform API key with the scope `security:assessments:write`,\naccepted only by the assessment, producer and protocol routes. It\nacts in the organisation it was minted in; an unknown or revoked key\nis 401 `invalid_api_key`, and any other route answers 403\n`api_keys_not_supported`.\n","scheme":"bearer","type":"http"}}},"externalDocs":{"description":"Ironfang Security documentation","url":"https://ironfang.com/security/docs"},"info":{"contact":{"email":"hello@ironfang.com","name":"Ironfang","url":"https://ironfang.com/contact"},"description":"Ironfang Security helps an organisation understand what it exposes to\nthe internet, fix what matters and keep evidence that it did.\n\nThe first service is the External Security Check: a free, low-impact\nexternal assessment of a domain the organisation has proved it\ncontrols. It reads DNS, TLS, HTTP, email-domain and service-exposure\nconfiguration. It does not attempt exploitation, authentication or\nanything intrusive, and it is not a penetration test or a certification.\n\nThe authority chain is explicit: a domain is added, its ownership is\nverified with a DNS TXT record, the organisation confirms it is\nauthorised to have it assessed under a versioned scan policy, and only\nthen can scans run. Names found in certificate transparency logs are\nlisted as discoveries and are never scanned automatically.\n\nFindings are structured objects with a severity (how bad it would be)\nand a separate confidence (how sure Ironfang is). Each finding carries\nthe evidence that was observed, remediation guidance and its history.\nA finding can be rechecked after a fix; the recheck repeats the checks\nbehind it and records the result.\n\nEvery finding, whatever produced it, is in one canonical shape: the\nIronfang Finding Format. The External Security Check is one producer;\nagents, integrations and imports submit theirs through the assessment\nroutes (Assessments, Producers), and every list and detail here returns\nthem alike. A finding has a namespaced, permanent `check_id`, an `asset`\nand a `resource` on it, a `source`, its classifications, structured\nremediation, evidence with its sensitivity, and its sightings.\n\nEverything is organisation-bound: an object in another organisation is\nreported as not found. Authenticate with a Warden user token and act in\na tenant with `X-Ironfang-Tenant`. Reads need `security.read`; adding\ndomains, confirming authorisation, starting scans and changing findings\nneed `security.write`; submitting assessments needs\n`security.assessments.write`. The assessment and producer routes also\naccept a platform API key with the scope `security:assessments:write`;\nevery other route refuses API keys.\n\nEvery error is JSON of the shape `{\"error\": {\"code\", \"message\", \"docs\"},\n\"request_id\"}`: branch on `code` and the HTTP status, never on `message`.\nWhen the service is switched off the API answers 503 with code\n`security_disabled`; when scanning is paused, starting scans and\nverification checks answer 503 `scans_paused` while reads keep working.\n","license":{"name":"Proprietary - use governed by the Ironfang terms of service","url":"https://ironfang.com/legal/terms"},"summary":"External Security Check - verify a domain, run a low-impact external assessment, fix and recheck findings.","termsOfService":"https://ironfang.com/legal/terms","title":"Ironfang Security API","version":"0.2.0"},"openapi":"3.1.0","paths":{"/v1/activity":{"get":{"operationId":"listActivity","parameters":[{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ActivityItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items","next_cursor"],"type":"object"}}},"description":"Activity, newest first."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Activity","tags":["Activity"]}},"/v1/assessments":{"get":{"description":"Every collection run in the organisation, newest first, External Security Checks included.","operationId":"listAssessments","parameters":[{"in":"query","name":"asset_id","required":false,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"source_type","required":false,"schema":{"$ref":"#/components/schemas/SourceType"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Assessment"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items","next_cursor"],"type":"object"}}},"description":"Assessments."},"401":{"$ref":"#/components/responses/Problem"},"403":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"List assessments","tags":["Assessments"]},"post":{"description":"Starts one collection run by one producer against one asset. The asset is named by id, or by type and name (created, with its parents, when it does not exist). With a `client_reference` the call is idempotent: the same reference answers 200 with the same assessment. An assessment not completed within 24 hours fails and resolves nothing.","operationId":"startAssessment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartAssessmentRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Assessment"}}},"description":"Already started with this client_reference."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Assessment"}}},"description":"Started."},"409":{"$ref":"#/components/responses/Problem"},"422":{"$ref":"#/components/responses/Problem"},"429":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"Start an assessment","tags":["Assessments"]}},"/v1/assessments/{assessmentId}":{"get":{"description":"Where it is, what it received, and what it did to findings (observed, new, reopened, resolved).","operationId":"getAssessment","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Assessment"}}},"description":"The assessment."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"Get an assessment","tags":["Assessments"]},"parameters":[{"$ref":"#/components/parameters/AssessmentId"}]},"/v1/assessments/{assessmentId}/batches/{batchId}":{"parameters":[{"$ref":"#/components/parameters/AssessmentId"},{"$ref":"#/components/parameters/BatchId"}],"put":{"description":"Up to 500 findings and 2,000 coverage entries, 2 MiB. Idempotent: the same batch id with the same bytes answers 200 with the first response (`replayed: true`); different bytes under the same id are 409 `batch_conflict`. A finding that is not valid is rejected on its own and named in `rejected`; coverage that is not valid refuses the whole batch. A result id the assessment already has counts as a duplicate.","operationId":"uploadBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}},"description":"The same batch, sent again."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}},"description":"Accepted."},"400":{"$ref":"#/components/responses/Problem"},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"413":{"$ref":"#/components/responses/Problem"},"422":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"Upload a batch of findings and coverage","tags":["Assessments"]}},"/v1/assessments/{assessmentId}/complete":{"parameters":[{"$ref":"#/components/parameters/AssessmentId"}],"post":{"description":"Finishes the assessment. `completed` and `partial` resolve the findings this assessment's coverage examined (outcome `completed`, and nothing `failed` or `skipped` for the same thing) that it did not see; `failed` and `cancelled` resolve nothing. Completing again with the same status answers the assessment; with another, 409.","operationId":"completeAssessment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteAssessmentRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Assessment"}}},"description":"The assessment."},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"422":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"Complete an assessment","tags":["Assessments"]}},"/v1/changes":{"get":{"description":"Changes across the organisation's domains, newest first.","operationId":"listChanges","parameters":[{"in":"query","name":"domain_id","required":false,"schema":{"format":"uuid","type":"string"}},{"description":"Only changes this scan found.","in":"query","name":"scan_id","required":false,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"group","required":false,"schema":{"$ref":"#/components/schemas/ChangeGroup"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ChangeEvent"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items","next_cursor"],"type":"object"}}},"description":"Changes."},"400":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"List changes","tags":["Changes"]}},"/v1/changes/{changeId}":{"get":{"operationId":"getChange","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeEvent"}}},"description":"The change."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Get a change","tags":["Changes"]},"parameters":[{"in":"path","name":"changeId","required":true,"schema":{"format":"uuid","type":"string"}}]},"/v1/changes/{changeId}/acknowledge":{"parameters":[{"in":"path","name":"changeId","required":true,"schema":{"format":"uuid","type":"string"}}],"post":{"description":"Records that someone has reviewed the change. It never changes the finding it is about. Acknowledging twice keeps the first.","operationId":"acknowledgeChange","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeEvent"}}},"description":"The change, acknowledged."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Acknowledge a change","tags":["Changes"]}},"/v1/domains":{"get":{"operationId":"listDomains","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/DomainSummary"},"type":"array"}},"required":["items"],"type":"object"}}},"description":"The organisation's domains, oldest first."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"List domains","tags":["Domains"]},"post":{"description":"Adds a domain and issues a DNS TXT verification challenge. Accepts what a person would type (a URL or a name with a trailing dot) and normalises it. Refuses IP addresses, public suffixes and reserved names. Adding a domain that was removed earlier restores it.","operationId":"addDomain","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddDomainRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}},"description":"The domain, with its verification challenge."},"400":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"422":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Add a domain","tags":["Domains"]}},"/v1/domains/{domainId}":{"delete":{"description":"Stops all checks of the domain and removes it from the list. Its scan history, findings and evidence are kept for the audit trail.","operationId":"removeDomain","responses":{"204":{"description":"Removed."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Remove a domain","tags":["Domains"]},"get":{"operationId":"getDomain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}},"description":"The domain."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Get a domain","tags":["Domains"]},"parameters":[{"$ref":"#/components/parameters/DomainId"}]},"/v1/domains/{domainId}/authorisation":{"parameters":[{"$ref":"#/components/parameters/DomainId"}],"post":{"description":"Records that the acting user confirmed the current scan policy's statement for this verified domain. The record is immutable and names the policy and statement versions. A new policy version requires a new confirmation.","operationId":"authoriseDomain","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthoriseRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}},"description":"The domain with its authorisation."},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"422":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Confirm authorisation to assess","tags":["Domains"]}},"/v1/domains/{domainId}/discoveries":{"get":{"description":"Names found in certificate transparency logs. They are listed for review only and are not scanned.","operationId":"listDiscoveries","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Discovery"},"type":"array"}},"required":["items"],"type":"object"}}},"description":"Discoveries, alphabetically."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Names discovered for a domain","tags":["Domains"]},"parameters":[{"$ref":"#/components/parameters/DomainId"}]},"/v1/domains/{domainId}/monitoring":{"delete":{"description":"Scheduled checks stop. The domain's scan history and findings are kept.","operationId":"disableMonitoring","responses":{"204":{"description":"Monitoring is off."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Switch off monitoring","tags":["Monitoring"]},"get":{"description":"Whether the domain is monitored, when it is next checked, and whether monitoring can be switched on now (with the reason when not).","operationId":"getMonitoring","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitoring"}}},"description":"The domain's monitoring."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"A domain's monitoring","tags":["Monitoring"]},"parameters":[{"$ref":"#/components/parameters/DomainId"}],"patch":{"description":"A new frequency or a resume takes the policy's next slot. A manual check never moves the schedule.","operationId":"updateMonitoring","requestBody":{"content":{"application/json":{"schema":{"properties":{"frequency":{"$ref":"#/components/schemas/MonitoringFrequency"},"paused":{"description":"true pauses, false resumes.","type":"boolean"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitoring"}}},"description":"The domain's monitoring."},"409":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Change frequency, pause or resume","tags":["Monitoring"]},"post":{"description":"Only for a verified, authorised domain, within the organisation's monitored-domain limit. The first scheduled check runs within a few minutes unless a full check finished in the last day.","operationId":"enableMonitoring","requestBody":{"content":{"application/json":{"schema":{"properties":{"frequency":{"$ref":"#/components/schemas/MonitoringFrequency"}},"required":["frequency"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitoring"}}},"description":"Monitoring is on."},"409":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Switch on monitoring","tags":["Monitoring"]}},"/v1/domains/{domainId}/scans":{"parameters":[{"$ref":"#/components/parameters/DomainId"}],"post":{"description":"Queues a full scan of a verified, authorised domain. The verification record is looked up again first; if it has been removed the domain returns to unverified and the scan is refused. Subject to a cooldown per domain, a daily limit and one running scan per organisation.","operationId":"startScan","responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}},"description":"The queued scan."},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"429":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Run the External Security Check","tags":["Scans"]}},"/v1/domains/{domainId}/verification/check":{"parameters":[{"$ref":"#/components/parameters/DomainId"}],"post":{"description":"Looks up the TXT record immediately rather than waiting for the automatic recheck. Limited to one check every few seconds per domain.","operationId":"checkVerification","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}},"description":"The domain after the check."},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"429":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Check the verification record now","tags":["Domains"]}},"/v1/domains/{domainId}/verification/renew":{"parameters":[{"$ref":"#/components/parameters/DomainId"}],"post":{"description":"Replaces an expired or failed challenge with a new token. Refused while the domain is verified.","operationId":"renewVerification","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}},"description":"The domain with its new challenge."},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Issue a new verification token","tags":["Domains"]}},"/v1/findings":{"get":{"description":"Findings across the organisation from every producer, most severe first. By default only findings that still ask something of you (open, in_progress) are listed; pass `status` to choose.","operationId":"listFindings","parameters":[{"in":"query","name":"asset_id","required":false,"schema":{"format":"uuid","type":"string"}},{"deprecated":true,"description":"The same as `asset_id`.","in":"query","name":"domain_id","required":false,"schema":{"format":"uuid","type":"string"}},{"description":"Only findings observed in this assessment.","in":"query","name":"assessment_id","required":false,"schema":{"format":"uuid","type":"string"}},{"description":"Only findings observed in this scan (an External Security Check's assessment has the scan's id).","in":"query","name":"scan_id","required":false,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"source_type","required":false,"schema":{"$ref":"#/components/schemas/SourceType"}},{"in":"query","name":"check_id","required":false,"schema":{"type":"string"}},{"description":"Comma-separated statuses, or `all`. The names used before 0.2.0 (acknowledged, fixed, accepted_risk, needs_review) are still accepted for one release.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Comma-separated severities.","in":"query","name":"severity","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/FindingSummary"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items","next_cursor"],"type":"object"}}},"description":"Findings."},"400":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"List findings","tags":["Findings"]}},"/v1/findings/{findingId}":{"get":{"description":"What was found, why it matters, the evidence, how to fix it and its history.","operationId":"getFinding","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Finding"}}},"description":"The finding."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Get a finding","tags":["Findings"]},"parameters":[{"$ref":"#/components/parameters/FindingId"}],"patch":{"description":"Sets open, in_progress, accepted, suppressed or false_positive, with an optional note. `resolved` is set by an assessment that observes the fix; a person may set it only on manual and imported findings, which nothing will check again. A resolved finding is reopened before it is given another status.","operationId":"updateFinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFindingRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Finding"}}},"description":"The finding."},"404":{"$ref":"#/components/responses/Problem"},"422":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Change a finding's status","tags":["Findings"]}},"/v1/findings/{findingId}/recheck":{"parameters":[{"$ref":"#/components/parameters/FindingId"}],"post":{"description":"Repeats the checks behind this finding on its host. If the condition is no longer observed the finding becomes resolved; its evidence and history are kept. Only the External Security Check's findings can be rechecked (409 `recheck_unavailable` otherwise).","operationId":"recheckFinding","responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}},"description":"The recheck scan."},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"429":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Recheck a finding","tags":["Findings"]}},"/v1/monitoring":{"get":{"description":"Every domain with monitoring on or paused, with its schedule and health.","operationId":"listMonitoring","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"frequencies":{"items":{"$ref":"#/components/schemas/MonitoringFrequency"},"type":"array"},"items":{"items":{"$ref":"#/components/schemas/Monitoring"},"type":"array"},"offered":{"description":"Whether this organisation can use monitoring at all.","type":"boolean"},"usage":{"properties":{"max":{"type":"integer"},"used":{"type":"integer"}},"required":["used","max"],"type":"object"}},"required":["items","offered","usage","frequencies"],"type":"object"}}},"description":"Monitored domains."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Monitored domains","tags":["Monitoring"]}},"/v1/notification-preferences":{"get":{"description":"The caller's own choices for in-app and email notifications in this organisation. A channel with `custom: false` uses the recommended set: every change in-app; by email, critical and high issues and their return, a material severity increase, imminent certificate expiry, an important newly exposed service and monitoring stopping. Needs security.read only.","operationId":"getNotificationPreferences","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferences"}}},"description":"The preferences."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Your notification preferences","tags":["Notifications"]},"patch":{"description":"For each channel: leave it out to keep it, send an object to save your own filters, or `null` to return to the recommended set. Needs security.read only: these are your own.","operationId":"updateNotificationPreferences","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"allOf":[{"$ref":"#/components/schemas/NotificationPreference"}],"nullable":true},"in_app":{"allOf":[{"$ref":"#/components/schemas/NotificationPreference"}],"nullable":true}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferences"}}},"description":"The preferences now."},"400":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Change your notification preferences","tags":["Notifications"]}},"/v1/overview":{"get":{"description":"The organisation's domains, open findings by severity, the latest scan, the top recommended actions and recent activity.","operationId":"getOverview","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Overview"}}},"description":"Overview."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Security overview","tags":["Service"]}},"/v1/producers":{"get":{"description":"The organisation's registered agents and integrations, and what each can check and fix.","operationId":"listProducers","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Producer"},"type":"array"}},"required":["items"],"type":"object"}}},"description":"Producers."},"401":{"$ref":"#/components/responses/Problem"},"403":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"List producers","tags":["Producers"]}},"/v1/producers/{instanceId}":{"parameters":[{"$ref":"#/components/parameters/InstanceId"}],"put":{"description":"Creates or updates the producer with this instance id and type. Remediation actions this server does not know are listed in `ignored`, so a producer newer than the server learns what it supports.","operationId":"registerProducer","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterProducerRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProducerRegistration"}}},"description":"Updated."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProducerRegistration"}}},"description":"Registered."},"422":{"$ref":"#/components/responses/Problem"},"429":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"Register a producer and its capabilities","tags":["Producers"]}},"/v1/protocol":{"get":{"description":"Supported protocol versions, limits, vocabularies (source types, asset types, categories, classification schemes, evidence kinds, sensitivities, statuses) and the remediation action registry, so a producer can check before it sends.","operationId":"getProtocol","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Protocol"}}},"description":"The protocol."},"401":{"$ref":"#/components/responses/Problem"},"403":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":[]},{"platformApiKey":[]}],"summary":"What this server speaks","tags":["Assessments"]}},"/v1/scan-policy":{"get":{"description":"What the External Security Check includes and never does, and the statement the organisation confirms to authorise it.","operationId":"getScanPolicy","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanPolicy"}}},"description":"The current policy."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Current scan policy","tags":["Service"]}},"/v1/scans":{"get":{"operationId":"listScans","parameters":[{"in":"query","name":"domain_id","required":false,"schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ScanSummary"},"type":"array"},"next_cursor":{"description":"Opaque cursor for the next page; empty on the last page.","type":"string"}},"required":["items","next_cursor"],"type":"object"}}},"description":"Scans, newest first."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Scan history","tags":["Scans"]}},"/v1/scans/{scanId}":{"get":{"operationId":"getScan","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}},"description":"The scan."},"404":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Get a scan and its results","tags":["Scans"]},"parameters":[{"$ref":"#/components/parameters/ScanId"}]},"/v1/scans/{scanId}/cancel":{"parameters":[{"$ref":"#/components/parameters/ScanId"}],"post":{"operationId":"cancelScan","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}},"description":"The scan after cancellation."},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Cancel a queued or running scan","tags":["Scans"]}},"/v1/scans/{scanId}/compare/{otherScanId}":{"get":{"description":"Findings that appeared, were resolved or came back between two scans of the same domain, in either order. Only categories that completed in both scans are compared, on the hosts both covered. A scan's `previous_scan_id` is the natural one to compare with.","operationId":"compareScans","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanComparison"}}},"description":"The comparison."},"400":{"$ref":"#/components/responses/Problem"},"404":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"default":{"$ref":"#/components/responses/Problem"}},"summary":"What changed between two scans","tags":["Scans"]},"parameters":[{"$ref":"#/components/parameters/ScanId"},{"in":"path","name":"otherScanId","required":true,"schema":{"format":"uuid","type":"string"}}]},"/v1/status":{"get":{"description":"Whether Security is enabled, paused or switched off, the free-tier limits that apply, and the scanner's identity (User-Agent and source addresses) for allowlisting.","operationId":"getStatus","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceStatus"}}},"description":"Status."},"default":{"$ref":"#/components/responses/Problem"}},"summary":"Service status and limits","tags":["Service"]}}},"security":[{"bearerAuth":[]}],"servers":[{"url":"https://api.ironfang.com/security"}],"tags":[{"description":"Whether Security is available, and the limits that apply.","name":"Service"},{"description":"Domains the organisation has added, their ownership verification and authorisation.","name":"Domains"},{"description":"External Security Check runs and their results.","name":"Scans"},{"description":"Normalised findings from every producer, their evidence, sightings, status and rechecks.","name":"Findings"},{"description":"How a producer (an agent, an integration, an import) submits results: start an assessment, upload batches of findings and coverage, complete it. Batches are idempotent; only coverage a completed assessment reports can resolve a finding. See https://ironfang.com/security/docs.","name":"Assessments"},{"description":"The agents and integrations that submit assessments, and what each can check and fix.","name":"Producers"},{"description":"What happened in the organisation's Security account.","name":"Activity"},{"description":"What changed about a domain's security between checks: issues found, resolved or back, services exposed, certificates replaced or about to expire, DNS and mail records changed, and scheduled checks that could not run. Routine renewals, record order and address changes behind a CDN are not changes.","name":"Changes"},{"description":"Who hears of a change, and how. Deliveries are made by the Ironfang API: in-app through the notification centre, email to the member's verified address. Security never holds addresses.","name":"Notifications"},{"description":"Scheduled External Security Checks of verified domains. A monitored domain is checked daily or weekly at a fixed time, and monitoring pauses with a reason when the domain stops being verified or authorised.","name":"Monitoring"}]}