
Compliance
CERT-In Audit: The Evidence an Empanelled Auditor Asks For
What a CERT-In empanelled auditor asks for, and how to make infrastructure produce it: scoped inventory, artefact hashes, change history, access-path evidence.
The engagement letter is signed, a date sits in the calendar, and the questions start. Which assets are in scope. Which version is running. Which build produced the image serving traffic today, and which served it in April. Who could reach that namespace last quarter. Clause-by-clause readings of the July 2025 guidelines exist, written from the CISO's chair. This is the platform read.
The Guidelines Bind the Auditee, Not Just the Auditor
The Comprehensive Cyber Security Audit Policy Guidelines — Version 1.0, dated 25.07.2025 — address two parties: empanelled auditing organisations, and auditee organisations, "the organization that owns or operates the systems, processes, and infrastructure that is being evaluated", in "both the public and private sectors". Half the document is instructions to the audited party. Auditees are "expected to ensure a comprehensive audit covering all aspects of their ICT systems at least once a year" — the coverage expectation these guidelines set, not a new statutory duty on every private company. Modals carry weight: *must*, *shall*, *should*, *is recommended* and *may advise* mix inside single clauses, and promoting one into another is how a board gets briefed on duties that do not exist.
One clause drags existing duties inside the engagement: every assignment must include verification of compliance with CERT-In's 28 April 2022 Directions, with "findings along with relevant evidences" in the report. The six-hour clock and 180-day retention mandate are covered separately; here they become things an auditor makes you evidence, on their timetable.
The auditor asks hard because the auditor is exposed: graded action for adverse reports and poor-quality audits runs "a) Move to watch list with warning & written commitment b) Suspension c) Debarment as per GFR and De-empanel by CERT-In d) Penal & Legal Actions". The roster is a single PDF, "updated by us as soon as there is any change"; the copy retrieved on 10 September 2026 ran to 236 entries — a snapshot, not a standing figure.
Scope Is a Query Against Inventory, Not a Paragraph in an RFP
The guidelines are blunt about scope: "The scope must be derived from the consolidated and updated asset inventory of the organization. The asset inventory should be reviewed and updated periodically by the IT team." Deriving scope is a *must*; keeping the inventory current a *should*. An organisation without an inventory has no defensible scope, only a negotiated one.
Two clauses shape what it carries. The auditee "should provide a comprehensive scope" covering "testing / UAT, development, and production environments", so every forgotten dev cluster is in. Version-specific details of web and mobile applications "must be explicitly mentioned in the audit scope and report". There is also a date: the auditor "may advise" stating the date the inventory was updated to, and once stated "this date must be reflected in the audit reports" — so have the inventory emit its own as-of instant.
#!/usr/bin/env bash
# Cluster-hosted slice of the asset inventory, with an as-of instant.
set -euo pipefail
CONTEXT="${1:?usage: cluster-inventory.sh <kube-context>}"
AS_OF="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
OUT="audit-scope/cluster-inventory-${AS_OF}.json"
mkdir -p audit-scope
kubectl --context "$CONTEXT" get pods --all-namespaces -o json \
| jq --arg as_of "$AS_OF" --arg cluster "$CONTEXT" '{
as_of: $as_of,
cluster: $cluster,
workloads: [ .items[] | {
namespace: .metadata.namespace,
pod: .metadata.name,
owner: ((.metadata.ownerReferences // [])[0].name // ""),
service_account: (.spec.serviceAccountName // "default"),
containers: [ (.status.containerStatuses // [])[] | {
name: .name,
image_ref: .image,
resolved_digest: .imageID
} ]
} ]
}' > "$OUT"
# The inventory is evidence too: hash it.
sha256sum "$OUT" | tee "${OUT}.sha256"That output is a slice: cluster-hosted workloads, nothing else. The inventory the clause points at is organisation-wide — endpoints, network devices, identity systems, off-cluster databases and SaaS stay in scope whether or not kubectl sees them. What it buys: the fastest-moving part of the estate stops being hand-maintained, against the marker it is scored on, csm.6.
The Identity of the Audited Thing: Hash, Version, Timestamp
A certificate saying "the application was audited" is worth little if nobody can say which build that was. "It is recommended that audit-related artifacts, such as hash values, versions, and timestamps, be captured by the auditee organization and shared with the auditing organization", and those details "should be prominently featured in the audit certificate and reports". Recommended, not mandated — but captured *by the auditee*: a platform requirement in policy costume.
A harder version sits in a narrower place. Clause 15.2.3.ii covers a website on a staging server or testing environment provided by the hosting service provider, which the auditor must test before issuing the certificate; inside that item, "Application hash values and version numbers must be obtained from the auditee and included in the audit report". A *must*, confined to the hosted-website case.
The mapping to a cluster is this article's, not CERT-In's: the guidelines name neither Kubernetes nor image digests, and anyone briefing a board that CERT-In requires digest pinning has been misled. What is true is that a mutable tag cannot be an artefact hash — as Kyverno's require-image-checksum sample puts it, "tags are mutable and can be overwritten".
# CERT-In names neither Kyverno nor image digests anywhere.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-image-digest
annotations:
policies.kyverno.io/description: >-
Tags are mutable, so a tag cannot identify the build that was audited.
spec:
background: true
rules:
- name: require-image-digest
match:
any:
- resources:
kinds: [Pod]
# Stand-ins: list your own in-scope namespaces here.
namespaces: [payments, ledger]
validate:
# The library sample ships as Audit, which admits and reports.
failureAction: Enforce
message: "In-scope images must be referenced by sha256 digest."
pattern:
spec:
containers:
- image: "*@sha256:*"
"=(initContainers)":
- image: "*@sha256:*"
"=(ephemeralContainers)":
- image: "*@sha256:*"The pattern is tighter than the sample's "*@*", which accepts any digest algorithm. Kyverno's verifyImages rule is the other tool: it checks each image "for a digest" when verifyDigest is true (the default) and "mutates matching images to add the image digest" by default, because a digest makes a reference immutable. Stronger, but it demands signatures too — the wrong rule when the requirement is only that a version be nameable. Both are behaviours of a documented Kyverno version, not fixed properties.
A digest identifies the artefact, not its origin. Sigstore's cosign builds in-toto attestations from a predicate file — cosign attest --predicate <file> --key cosign.key <image> — verifies them with cosign verify-attestation, and pushes the attestation to the registry beside the image. Building that chain is the supply-chain piece; here it is read back.
#!/usr/bin/env bash
# cosign and in-toto are not CERT-In requirements: they are one way to
# produce the hash / version / timestamp set the guidelines recommend.
set -euo pipefail
NS="${1:?usage: artefact-evidence.sh <namespace>}"
KEY="${COSIGN_KEY:-cosign.pub}"
mkdir -p evidence
kubectl get pods -n "$NS" \
-o jsonpath='{range .items[*].status.containerStatuses[*]}{.imageID}{"\n"}{end}' \
| sed 's#^docker-pullable://##' | sort -u | while read -r ref; do
[ -n "$ref" ] || continue
safe="$(printf '%s' "$ref" | tr '/:@' '___')"
# --type takes ONE alias and v0.2/v1 are separate ones, so try each.
for t in slsaprovenance slsaprovenance1; do
cosign verify-attestation --key "$KEY" --type "$t" "$ref" \
| jq -r '.payload' | base64 -d | jq '.' \
> "evidence/${safe}.provenance.json" && break
done
# Predicate shape differs between the two — read whichever landed.
jq --arg ref "$ref" '{
image: $ref,
digest: ($ref | split("@") | last),
source_commit: (.predicate.buildDefinition.resolvedDependencies[0].digest.gitCommit
// .predicate.materials[0].digest.sha1),
built_at: (.predicate.runDetails.metadata.startedOn
// .predicate.metadata.buildStartedOn)
}' "evidence/${safe}.provenance.json" > "evidence/${safe}.artefact.json"
done
jq -s '{ generated_at: (now | todateiso8601), artefacts: . }' \
evidence/*.artefact.json > evidence/artefact-manifest.json
sha256sum evidence/artefact-manifest.jsonChange History an Auditor Can Backtrack
Clause 9.5 has two items, and the first holds two sentences. Item i opens with restraint — "The application developer should avoid making any code changes to the audited application or infrastructure, after issuance of the audit certificate" — and closes with the hash, version and timestamp recommendation quoted above. Item ii is a capability: "Version control and change management be effectively implemented so that the assets that were/are part of audit scope can be backtracked." No *must*, no *shall*. Its marker is pro.19, change control "defined and implemented".
Backtracking walks from what runs to what produced it; the durable link is the attestation, not the delivery controller's memory. Argo CD bounds its own history: revisionHistoryLimit "limits the number of items kept in the application's revision history, which is used for informational purposes as well as for rollbacks", and zero stores none — a sync log with a retention policy, not an audit trail.
Clause 16.3.v says the final report "should be issued after the closure of vulnerabilities & completion of follow-up audit of the application hosted on production environment" — a *should* — while the same clause carries a *must*: if scope was limited to staging, "the report must explicitly state that the audit was not conducted on production environment". Between draft and follow-up the platform moves; the change record keeps that follow-up a re-check.
Access-Path Evidence: Who Could Reach It, and How
Two separate clauses govern access, and fusing them invents a control that does not exist. On privileged testing, the auditee "must provide only temporary access such as login credentials, access tokens, certificates, or secure ID numbers" and "must ensure that all such privileges are revoked immediately upon completion". On remote access, traffic "should be tunneled, encrypted and logged" and "MFA is mandatory for remote access of the cyber infrastructure". Both apply when auditor access is remote and privileged; they stay two clauses.
The harder question is who could reach an in-scope namespace, and how. A dump of RoleBinding objects only lists grants, leaving the reader to compute the union — including cluster-wide bindings nobody remembers. Kubernetes ships the resolver — kubectl auth can-i --list prints all allowed actions in a namespace, and --as impersonates "a regular user or a service account". Groups are a different flag: --as-group, which "can be repeated to specify multiple groups".
#!/usr/bin/env bash
# "Who could reach this namespace", by evaluation, not inference.
set -euo pipefail
NS="${1:?usage: access-matrix.sh <namespace>}"
AS_OF="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
# Impersonate-Group "Requires Impersonate-User": pair it with a throwaway.
PROBE="${PROBE_USER:-audit-probe-no-bindings}"
mkdir -p audit-scope
# Namespace-bound subjects, plus cluster-wide ones inheriting into it.
{ kubectl get rolebindings -n "$NS" -o json
kubectl get clusterrolebindings -o json
} | jq -rs --arg ns "$NS" '
[ .[].items[] | .subjects // [] ] | add // []
| map(if .kind == "ServiceAccount"
then "ServiceAccount|system:serviceaccount:"
+ (.namespace // $ns) + ":" + .name
else (.kind // "User") + "|" + .name
end)
| unique | .[]' \
| while IFS='|' read -r kind name; do
printf '\n## %s %s\n' "$kind" "$name"
if [ "$kind" = "Group" ]; then
kubectl auth can-i --list --namespace "$NS" \
--as "$PROBE" --as-group "$name"
else
kubectl auth can-i --list --namespace "$NS" --as "$name"
fi
done | tee "audit-scope/access-matrix-${NS}-${AS_OF}.txt"The output is a point-in-time answer, which is why the timestamp goes in the filename. An auditor asking about last quarter needs the API-server audit log instead — a build covered in Kubernetes audit logs into a SIEM you operate.
Identity runs the other way too. Auditees "must verify the identity, official identity cards/ government issued documents and designations of the auditing team", and auditing organisations "should not field freelancers, interns, freshers, moonlighters, third party consultant" or staff on notice. The firm must deploy "only manpower declared to CERT-In in Snapshot Information Form" — the names on the engagement are checkable facts.
From Alert to Artefact: The Chain the Auditor Walks
The document an auditor builds a programme against is the Cyber Security Audit Baseline Requirements, NSCS-46-16 Rev 1.0, October 2020 — nearly six years old, still the reference the July 2025 guidelines name. It is "mandatorily applicable to owners and regulators of Critical Information Infrastructure", others "strongly encouraged to follow" it. Controls sit in six categories — Management, Protection, Detection, Response, Recovery, Lessons Learnt & Improvements — and Detection hits the platform team first: log collection scope, mechanism and frequency, and "Synchronisation with singular time source", det.8.
That second marker is where evidence chains quietly fail: if two systems disagree about what time it was, a correlation between them is an assertion, and log volume does not repair it. The 2022 Directions are specific: NTP servers of NIC or NPL, "or with NTP servers traceable to these NTP servers, for synchronisation of all their ICT systems clocks". Engineering that clock is Trusted time.
Audit evidence is defined to include "logs, observations, or other forms of data collected during the audit", and must be "accurate, relevant, and sufficient" and "properly documented and appended to the audit report" — log retention and provenance are the appendix, not a side quest. Scoring has a shape too: CVSS "for severity", EPSS "to assess the likelihood of real-world exploitation", and "every reported observation / vulnerability shall be mapped with Common Weakness Enumeration (CWE) and Common Vulnerabilities and Exposures (CVE) number". That needs candour: many Kubernetes findings are configuration defects with a clean CWE and no CVE in existence — a privileged container, a wildcard RBAC verb. Raise the gap; never attach a CVE that does not describe the finding.
Framework choice surprises teams whose programme runs on a checklist: "The limited lists such as OWASP Top 10, SANS Top 25 and similar, should not be considered as standards or references for audits." Coverage is expected against "comprehensive standards/frameworks like ISO/IEC, Cyber Security Audit Baseline Requirements, CSA Cloud Controls Matrix (CCM) for Cloud Security, Open Source Security Testing Methodology Manual (OSSTMM3)" — Top 10 mapping is a subset, not a scope.
What Leaves the Building: The Report, the Metadata, CERT-In
The engagement does not end at the auditee's boundary. Auditing organisations "must inform the auditee organisation, prior to the commencement of the audit assignment, about the requirement to share audit metadata and audit reports with CERT-In within five days of audit completion".
Two contract clauses are worth settling before signature: "Auditee organizations must seek the working notes upon completion of the audit (provisions for the same should be included in the audit contract)" and should ask that evidence collected "be submitted as an appendix along with the final audit report". Those make a finding reproducible next year by a different firm. A third is commercial. Arrangements "must be structured to maintain independence", and "payments to the auditing organization should not be contingent upon the outcome of the audit—whether favorable or unfavorable—nor should they be tied to the submission or approval of any closure reports". A milestone schedule paying on a clean certificate is the structure that clause exists to prevent.
One consequence belongs in pre-engagement design. In-scope assets that stay inaccessible "must be explicitly mentioned in the audit report, along with the reasons for their exclusion" and "must be brought to the notice of CERT-In". An asset you cannot open to inspection does not leave scope quietly; it becomes a named exclusion CERT-In reads. One rule gets over-read: the 282-control-point checklist that "shall form the default mandatory audit scope" is for critical systems of Ministries, Departments, Secretariats and Offices handling sensitive PII.
Exit Ramp: Evidence That Outlives the Auditor
Sector regulators layer on top. SEBI's Cybersecurity and Cyber Resilience Framework requires regulated entities to "engage only CERT-In empanelled IS auditing organizations for conducting external audits including cyber audit", caps any one of them at "a maximum period of three consecutive years" followed by "a cooling off period of two years", and requires an MD or CEO declaration with the report. That binds SEBI-regulated entities, not every Indian auditee — see RBI and SEBI cloud rules.
Rotation there is not a risk to manage but a schedule, arriving at least twice a decade: when the next firm starts, the evidence either transfers or gets rebuilt. If the trail lives in the outgoing auditor's portal, it is rebuilt at full cost.
The alternative is holding evidence in formats nobody licenses to you. The inventory slice is JSON with a hash beside it; the artefact manifest is JSON built from attestations that live in your registry and verify without a vendor; the access matrix is dated text; the change history is git. A new auditor gets a handover, not a rebuild — exit-ramp design applied to compliance artefacts.
The Long Game: An Evidence Surface, Not an Audit Sprint
The scope must be derived from the consolidated and updated asset inventory of the organization.
That sentence is the argument compressed: everything downstream — which versions were audited, what changed since, who could reach it, what an alert proves — queries something the platform either maintains continuously or reconstructs under pressure. Reconstruction is dearer, less accurate, and always due at the worst moment.
So treat the evidence surface as a permanent property of the platform, not a project spun up per engagement. The same inventory, digests, change records and access matrices answer an ISO 27001 Annex A scope question, a DPDP breach-workflow question and a customer security review — variations on four things: what runs, which version, what changed, who could touch it.
Regimes keep arriving; these guidelines are Version 1.0 of a 2025 document leaning on a 2020 baseline. Systems that describe themselves absorb that churn as a re-query. Systems that cannot pay the archaeology cost again each time. The audit is not the event: it is a read of infrastructure you either built to be legible, or did not.
§FAQ/Common questions
Frequently asked
What is a CERT-In audit?
It is a cyber security audit conducted by an organisation empanelled by CERT-In, governed by CERT-In's Comprehensive Cyber Security Audit Policy Guidelines (Version 1.0, 25.07.2025). The guidelines apply both to the empanelled auditing organisations and to auditee organisations — the ones that own or operate the systems being assessed — in the public and private sectors alike. In practice it is an evidence exercise: the scope must be derived from the organisation's consolidated asset inventory, every assignment must verify compliance with CERT-In's 28 April 2022 Directions, and audit evidence has to be documented and appended to the report.
What evidence does a CERT-In empanelled auditor ask the auditee for?
The guidelines put several artefacts on the auditee's side. The consolidated, periodically updated asset inventory the scope is derived from, and the date it was updated to — which, once the auditor advises stating it, must appear in the audit reports. Version-specific details of web and mobile applications, which must be explicitly mentioned in both the scope and the report. Audit-related artefacts such as hash values, versions and timestamps, which it is recommended the auditee capture and share. Version control and change management that lets in-scope assets be backtracked. Temporary privileged testing access, revoked immediately on completion.
Does CERT-In require image digests, Kyverno or signed attestations?
No. CERT-In's guidelines name none of those things. What they ask for is that artefacts such as hash values, versions and timestamps be capturable and shareable, and that in-scope assets be backtrackable through version control and change management. Digest pinning at admission and signed provenance attestations are one engineering way to satisfy that on a Kubernetes platform. Any mechanism producing an immutable artefact identity and a path back to the change that shipped it would serve the same clause.
How often does a CERT-In audit have to happen?
The guidelines describe auditee organisations as expected to ensure a comprehensive audit covering all aspects of their ICT systems at least once a year, and note that they may opt for additional assessments during the year. That is the coverage expectation these guidelines set for organisations within their scope, phrased as an expectation rather than a universal statutory mandate. Sector regulators are stricter and more specific: SEBI's CSCRF, for instance, requires regulated entities to use only CERT-In empanelled auditing organisations, caps any one of them at three consecutive years, and imposes a two-year cooling-off period after that.
What happens to the audit report after the engagement ends?
It leaves the building. Auditing organisations must inform the auditee, before the assignment starts, that audit metadata and audit reports will be shared with CERT-In within five days of audit completion. In-scope assets that stayed inaccessible must be named in the report with the reasons for their exclusion, and brought to CERT-In's notice. On the auditee's side, the guidelines say to seek the auditor's working notes on completion, with provisions for them in the audit contract, and to ask that the evidence collected be submitted as an appendix to the final report.
Further reading
- CERT-In Log Retention: India's 6-Hour Rule and 180 Days
- Kubernetes Audit Logs Into a SIEM You Operate: Wazuh
- Trusted Time: Chrony, PTP, and Logs That Hold Up in Audit
- ISO 27001 Without Inherited Controls: Annex A You Operate
- Supply Chain Security: SBOM, Sigstore and Admission Control
- RBI and SEBI Cloud Rules: India's BFSI Data Boundary
Executive Briefing
Thirty minutes to clarify your infrastructure risk
Walk us through your vendor footprint and regulatory constraints. We will tell you honestly where sovereignty creates leverage — and where it does not. No pitch deck. No obligation.