Skip to content
Stribog

Compliance

All writing

MeitY Empanelment: Architecting for Indian Government Cloud

MeitY empanelment certifies the provider, not your product. Workload classification, STQC audit access and exit clauses, mapped to real architecture.

Stribog13 min read

Search the term and the first page is provider marketing, every page answering one question: is that provider on the list. Underneath sit law-firm explainers for people who negotiate contracts. Between them, nothing for the person who has to build the thing — and the obligations that matter to them land in the runtime, not the policy folder. That is what separates an architecture that survives procurement review from a slide reading "MeitY compliant" over a stack that cannot prove where one log line was processed.

What Empanelment Actually Binds — and What It Does Not

MeitY has empanelled cloud service offerings from private providers, PSUs and MSMEs. The empanelment covers three deployment models — Public Cloud, Virtual Private Cloud and Government Community Cloud — across IaaS, PaaS and SaaS, as MeitY's Guidelines for Procurement of Cloud Services set out. Note those three labels: providers market their own names for government offerings, and vendor naming is not a fourth one.

The mechanics read best from a provider that has been through it, since the CSP Empanelment RFP is not publicly retrievable. One empanelled provider describes the sequence as a MeitY compliance check against that RFP, an audit of data centres and cloud service offerings by the Standardisation Testing and Quality Certification Directorate, a MeitY Letter of Award of Empanelment, then annual STQC surveillance audits. The same page restates a certification floor — ISO 27001:2017, ISO 27017:2015, ISO 27018:2019, ISO 20000-1:2018 — as the provider's restatement rather than MeitY text, lagging ISO/IEC 27001:2022.

Two consequences follow. First, empanelment attaches to infrastructure a specific provider operates, so its scope is whatever the audit covered. One empanelled provider states its empanelment covers services offered from its Asia Pacific (Mumbai) and Asia Pacific (Hyderabad) regions — a claim about itself, not a rule holding for every provider. Ask each one for its scope in writing.

Second, the sentence to take away: nothing here certifies your cluster. Managed service providers and systems integrators manage services provided by empanelled providers but, as one law-firm survey puts it, are not required to be empanelled themselves — while violations may result in temporary or permanent suspension of the service provider, or de-empanelment of the provider. You inherit the terms without the certificate.

Classify First: NISPG Categories Shape the Substrate

In March 2026 MeitY issued an Office Memorandum setting out a cloud selection framework for Central Ministries and Departments, in addendum to an earlier memorandum of November 2024. It is the most useful document in the stack for an architect because it makes the ordering explicit: departments are required to classify applications and data into the workload categories defined in the Ministry of Home Affairs' National Information Security Policy and Guidelines before selecting the cloud.

Workloads categorised as Top Secret and Secret are, per NISPG, not permitted to be hosted on cloud at all. Category A covers applications and data whose unauthorised disclosure could damage the security of the organisation, where compromise could cause serious harm to national security or national interests. Category B is essentially meant for official use, with limited operational disruption if compromised.

Table 1 maps bands to deployment options. Under Category A it offers government providers — NIC-provisioned data centre and cloud services, entities defined in Section 4i(c), State Data Centres — or sovereign cloud providers as and when notified by MeitY. Private empanelled providers offering virtual private cloud or public cloud, with DIC and NICSI, appear under Category B, which may also use every Category A option.

Classification happens before substrate selection, and substrate selection happens before you design anything. The vendor enters at the bottom of this flow, not the top.

Procurement Routes and the Contract Chain You Inherit

Cloud procurement is carried out in accordance with the General Financial Rules, 2017, and the memorandum sets out three routes: purchase orders on a nomination basis under Rule 204 of the GFR; rate contracting through Digital India Corporation or NICSI; or an open RFP or GeM purchase against MeitY-empanelled providers, whose deployment options are listed on the AMBUD portal. The guidelines put cloud services on GeM under a Professional Services and IT Services category — a pointer rather than a stable identifier, since marketplace taxonomies move.

The route decides who signs what, and therefore which obligations arrive at your door. A vendor or platform team is a subcontracted party: the department contracts a provider or an integrator, the empanelment terms sit in that contract, and your statement of work restates a subset. Nobody sends you the Empanelment RFP — only clauses derived from it.

So read your own contract for four things first: which substrate the department selected and under which category, who the third-party auditor may be, where processing must occur, and what the exit obligations are in days. Everything below is downstream of those answers. The DPDP Act demands the same discipline of any data fiduciary — but these obligations exist only because a government department is the buyer, and they bind before a contract exists.

Pinning the Estate: Region, Topology and the India Boundary

Start with what is solvable. If the contract names a substrate, the cluster should refuse to run workloads elsewhere, and that refusal belongs in the scheduler, not a runbook. Kubernetes has a hard constraint: nodeAffinity with requiredDuringSchedulingIgnoredDuringExecution, where the pod does not schedule unless the rule is met.

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: case-record-api
  namespace: gov-workload
spec:
  replicas: 6
  selector:
    matchLabels:
      app: case-record-api
  template:
    metadata:
      labels:
        app: case-record-api
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: topology.kubernetes.io/region
                    operator: In
                    values: ["ap-south-1", "ap-south-2"]
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: case-record-api
      containers:
        - name: api
          image: registry.example.in/gov/case-record-api:2.4.1
A hard region pin, plus a spread constraint so narrowing the placement set does not quietly collapse every replica into one zone. The region label values are your provider's — substitute your own.

A pin one team remembers is not a control. Push it to admission, where a workload without it is rejected rather than found during an audit. The field spelling has changed: enforcement now lives at spec.rules[*].validate[*].failureAction, and Kyverno's docs carry a deprecation warning against the older spec.validationFailureAction.

yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-permitted-region-pin
spec:
  background: true
  rules:
    - name: pods-must-pin-to-a-permitted-region
      match:
        any:
          - resources:
              kinds: [Pod]
              namespaces: [gov-workload]
      context:
        - name: regionValues
          variable:
            jmesPath: >-
              request.object.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[?key=='topology.kubernetes.io/region' && operator=='In'].values[]
            default: []
      validate:
        failureAction: Enforce
        message: >-
          Pods here must pin topology.kubernetes.io/region to a permitted
          region with a required nodeAffinity term.
        deny:
          conditions:
            any:
              - key: "{{ regionValues | length(@) }}"
                operator: Equals
                value: 0
              - key: "{{ regionValues }}"
                operator: AnyNotIn
                value: ["ap-south-1", "ap-south-2"]
Substrate drift blocked at admission — `Enforce` blocks the resource where `Audit` would only record it, the pattern our [Kyverno governance article](/blog/policy-as-code-kyverno-kubernetes-governance-scale) covers at estate scale. The context variable defaults to an empty list, so a pod with no affinity block fails the first condition rather than erroring on a missing path.

Now the part most estates get wrong. A region pin says where pods schedule; it says nothing about where data is processed, and the obligation is written in the language of the second. The procurement guidelines state, under their specific requirements for SaaS, that services under that model shall only be offered from data centres audited and qualified by STQC under the Cloud Services Empanelment process, and that providers shall be responsible for ensuring all data functions and processing are performed within the boundaries of India. That duty sits on the provider, in a SaaS annex — not a universal rule for every IaaS estate — but it is the sentence restated down the contract chain into your statement of work.

The gap lives outside the cluster: the managed control plane's own region, the image registry and its replicas, the log and metrics SaaS, the error tracker, the backup bucket and its replication, the identity provider, any vendor API on the request path. Each is a processing location a node label cannot see.

Two things this picture separates: the control that constrains where traffic may go, and the evidence recording where it went. An auditor asks for the second.

The control is a default-deny egress policy with an explicit allowlist. NetworkPolicy documentation is clear that pods are non-isolated for egress by default — all outbound connections allowed until some policy selects the pod and lists Egress in its policyTypes — and that a default deny-all egress policy also blocks DNS, making a separate cluster-DNS allow rule mandatory.

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
  namespace: gov-workload
spec:
  podSelector: {}
  policyTypes: [Egress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: gov-workload
spec:
  podSelector: {}
  policyTypes: [Egress]
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-estate-and-allowlisted-egress
  namespace: gov-workload
spec:
  podSelector: {}
  policyTypes: [Egress]
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              estate: gov-in
    - to:
        - ipBlock:
            cidr: 198.51.100.0/24
        - ipBlock:
            cidr: 203.0.113.0/24
      ports:
        - protocol: TCP
          port: 443
Three documents: default-deny egress; the DNS allow that stops it breaking everything; and one policy carrying both east-west traffic and the outbound allowlist. Those CIDRs are your own in-India endpoint ranges — RFC 5737 documentation ranges stand in here. No canonical machine-readable "India CIDR list" exists, and a registry's country block would not be one.

State the limits out loud. NetworkPolicy is implemented by the network plugin, and creating the resource where the plugin does not implement it has no effect whatsoever. External destinations can only be expressed as IP CIDR ranges through ipBlock; there is no hostname matching. And as of Kubernetes 1.36 the API still cannot log the connections it blocked or accepted, so the policy is the control and something else must be the evidence — a CNI with flow logging, Cilium being the obvious one.

Audit Access Is a Runtime Requirement, Not a Paperwork Clause

The procurement guidelines put third-party audit support squarely on the managed service provider or systems integrator: provide support during audit by STQC, a MeitY-empanelled agency, or any agency appointed by the User Department, and support the auditor or internal IT team with respect to other requirements such as forensic investigations and SLA validation.

That is an engineering requirement, not a courtesy. You do not choose the auditor. Forensic investigation is named explicitly, so the evidence must survive the incident it describes; SLA validation means it must reconcile against numbers somebody else measures. And the most common failure is trivially avoidable: Kubernetes API server auditing is off unless you turn it on. The audit documentation defines four levels — None, Metadata, Request and RequestResponse — and if --audit-policy-file is not passed, no events are logged at all. Teams find this out during the audit, when the period has already elapsed.

yaml
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages: [RequestReceived]
rules:
  - level: None
    nonResourceURLs:
      ["/healthz*", "/livez*", "/readyz*", "/version", "/metrics"]

  - level: RequestResponse
    resources:
      - group: rbac.authorization.k8s.io
        resources:
          [roles, rolebindings, clusterroles, clusterrolebindings]

  # Metadata only: never log the payload of a secret.
  - level: Metadata
    resources:
      - group: ""
        resources: [secrets, configmaps, serviceaccounts/token]

  - level: RequestResponse
    verbs: [create, update, patch, delete]
    resources:
      - group: networking.k8s.io
        resources: [networkpolicies]
      - group: kyverno.io
        resources: [clusterpolicies, policies]
      - group: apps
        resources: [deployments, statefulsets, daemonsets]

  # Everything else, read path included: metadata is enough, and cheap.
  - level: Metadata
A tiered audit policy: full bodies where access and boundary controls change — including the workload objects where a region pin disappears — metadata elsewhere, nothing for health churn. Contract-evidence tooling for a vendor estate, never a form of MeitY certification.

Three properties turn a log into evidence. It must leave the control-plane node it was written on, or an incident there destroys its own record. It must be retained past the window an auditor asks about, which for a forensic investigation exceeds operational retention. And it must be joinable with the CNI flow log: the audit trail proves what was configured, the flow log what crossed the boundary. Most of this overlaps with CERT-In's directions and with a SOC 2 examination — the argument for building the pipeline once.

Failure Modes That Lose the Contract

  • Classification drift. The department classified at bid time; two years on, the application has absorbed a dataset that classification does not describe. It is their prerogative, so nobody's calendar item on your side.
  • Region drift. A pin on the original Deployment but not on the Job, the CronJob, the debug pod, or the operator someone installed by Helm.
  • The control plane you forgot. A managed control plane runs in a region of its own and processes every API object you create.
  • Observability leaving the boundary. Logs, traces and error reports usually reach a foreign SaaS endpoint first, carrying the estate's most sensitive strings.
  • Auditing never enabled. No --audit-policy-file, therefore no events, therefore no evidence for a period that cannot be reconstructed.
  • The two exit numbers fused into one. The 45-day no-delete hold and the minimum 30-day backup floor are different clauses serving different purposes.
  • A hand-back rehearsed only as disk images, leaving behind the images, the volume data, the cluster state including custom resources, and the registry contents.

The Exit Ramp Is Already Written — Build to It

The unusual thing about this regime is that the exit is specified up front. The guidelines indicate a contract duration of only two years, with an option to extend for one additional year, stated explicitly to prevent vendor lock-in — an exit ramp designed in before the first invoice, closer to how sovereignty ought to work as architecture than most contracts get.

Two retention numbers govern the wind-down, and they are separate. As the guidelines restate the Empanelment RFP, the provider should not delete any data before 45 days from the expiry of the contract, and the managed service provider ensures compliance with that. Separately — again attributed to the RFP — the provider should offer a backup solution supporting a retention period of a minimum of 30 days, or as desired by the User Department. One is an exit hold from expiry; the other a backup floor running throughout the contract.

On format, the guidelines ask that data transmitted from the provider to the department leverage standard data formats, giving OVF and VHD as examples, "whenever possible". Those are VM-era examples, and an estate rehearsing its hand-back as disk images alone has not rehearsed a hand-back. Ownership is unambiguous: ownership of the data generated upon usage of the system, at any point during the contract or at its expiry or termination, rests absolutely with the Government Department. Once the exit is complete the provider must remove that data, content and other assets from the cloud environment and destroy them so they cannot be forensically recovered.

Two clauses, two clocks, one hand-back set. The container-native artefacts below the quoted clause are engineering translation, not guideline text.

The container-native mapping is mechanical. Images map to the OCI Image Layout, a directory of content-addressable blobs and location-addressable references intended to travel over archive formats such as tar — a reason to own your registry rather than rent it. Volume data maps to the VolumeSnapshot API, a standardised way to copy a volume's contents at a point in time where the CSI driver supports it. Cluster and application state — the API objects a disk image never contained — maps to Velero, which queries the API server for what to back up, uploads it to object storage, and snapshots persistent volumes by default. Registry contents are separate.

bash
#!/usr/bin/env bash
set -euo pipefail

NS="<NAMESPACE>"
OUT="<HANDBACK_DIR>"
REGISTRY="<REGISTRY_HOST>/<PROJECT>"
SNAP_CLASS="<SNAPSHOT_CLASS>"
EXPIRY="<YYYY-MM-DD>"

mkdir -p "$OUT"/{images,registry}

# 1. Images as an OCI image layout, archived.
kubectl -n "$NS" get pods \
  -o jsonpath='{range .items[*].spec.containers[*]}{.image}{"\n"}{end}' \
  | sort -u | while read -r ref; do
      name="$(basename "$ref" | tr ':@' '__')"
      skopeo copy --all "docker://$ref" "oci:$OUT/images/$name:exported"
    done
tar -C "$OUT/images" -cf "$OUT/images.tar" .

# 2. Volume data. Verify the CSI driver supports snapshots first.
kubectl -n "$NS" get pvc -o name | while read -r pvc; do
  claim="${pvc##*/}"
  kubectl apply -f - <<EOF
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: handback-$claim
  namespace: $NS
spec:
  volumeSnapshotClassName: $SNAP_CLASS
  source:
    persistentVolumeClaimName: $claim
EOF
done

# 3. Cluster and application state, CRDs included.
velero backup create "handback-$NS" --include-namespaces "$NS" \
  --include-cluster-resources=true --wait

# 4. Registry contents, as a separate deliverable.
skopeo sync --src docker --dest dir "$REGISTRY" "$OUT/registry"

# 5. Digests: what the department verifies, and what you can prove.
find "$OUT" -type f -print0 | xargs -0 sha256sum > "$OUT/MANIFEST.sha256"

cat > "$OUT/DESTRUCTION-CHECKLIST.md" <<EOF
Contract expiry: $EXPIRY
Earliest deletion (45-day hold): $(date -d "$EXPIRY +45 days" +%F)
[ ] Hand-back accepted in writing by the department
[ ] Data, content and assets removed from the cloud environment
[ ] Volumes, images and registry copies destroyed, non-recoverable
[ ] Destruction certified to the department
EOF
Exit-drill skeleton — deliberately templated; <PLACEHOLDER> values are yours. Run it against a scratch namespace long before expiry. Deletion is deliberately not in this script: nothing is destroyed inside the hold window.

Rehearse it. A restore you have never performed is a hypothesis — the same argument as in disaster recovery, where the drill is the evidence. Here a failed exit costs the department the data ownership it nominally holds in contract.

The Long Game: Build Once, Qualify Repeatedly

Read what this market demands and notice how little is specific to it. Substrate placement enforced at admission. An egress boundary with a named allowlist. An evidence pipeline that survives the incident it records. A rehearsed exit producing portable artefacts with a manifest. None of it is wasted elsewhere: those four controls carry a data-residency argument under the DPDP Act, make CERT-In's timelines survivable, supply what an information-security certification samples, and answer what a regulated financial-services buyer asks about localisation. Build them for a public-sector bid and you have the platform property that answers the next regulator without a project.

That is optionality in concrete form. An estate pinned to a permitted substrate can be pinned to a different one; one that can prove where its data was processed can prove it to a second auditor; one handed back in portable artefacts can be moved to a competitor — precisely what a two-year contract is designed to make possible.

One closing correction, because it starts every one of these conversations. There is no such thing as a MeitY-certified cluster, product or vendor. There is an empanelled provider, an STQC audit of its data centres and offerings, and a contract chain carrying real obligations to everyone underneath. The job is not to acquire a badge but to build an estate that answers, in artefacts, every question that chain asks.

§FAQ/Common questions

Frequently asked

Can my company or my Kubernetes cluster get MeitY empanelment?

No. Empanelment is granted to a cloud service provider for its data centres and cloud service offerings, following an audit by the Standardisation Testing and Quality Certification Directorate and a MeitY Letter of Award, with annual STQC surveillance audits thereafter. It is not a certification a software product, a systems integrator or a customer cluster can hold. Managed service providers and systems integrators manage services provided by empanelled providers without being empanelled themselves; their obligations arrive through the contract chain. Anyone offering to make your cluster "MeitY certified" is describing something that does not exist.

Does the March 2026 cloud selection framework prohibit private cloud providers for sensitive government workloads?

It does not prohibit anything. The Office Memorandum states that it does not impose any mandatory obligation or restriction on any Government department to comply with the advisory it contains, describes its Table 1 as an indicative framework, and states that classification of applications and data is the prerogative of the end-user department. What Table 1 does is map bands to options: under Category A it lists government providers — NIC, entities defined in Section 4i(c), State Data Centres — or sovereign cloud providers as and when notified by MeitY, while private MeitY-empanelled providers offering virtual private cloud or public cloud appear under Category B. Workloads categorised as Top Secret or Secret are, per NISPG, not permitted on cloud at all. Design to the table because it is what buyers are guided to ask for, not because it is a prohibition.

Is a Kubernetes region pin enough to satisfy an India data-processing requirement?

No, and this is the most consequential architectural mistake in this space. A nodeAffinity rule using requiredDuringSchedulingIgnoredDuringExecution constrains where pods schedule. A processing-boundary obligation is about where data functions and processing actually occur, which includes everything the cluster talks to: the managed control plane's own region, image registries, log and metrics SaaS, error trackers, backup targets and their replication, the identity provider, and any vendor API called on the request path. None of those are visible to a node label. Closing the gap needs a default-deny egress policy with an explicit allowlist plus a written inventory of out-of-cluster processors — and note that a default-deny egress policy also blocks DNS, so a separate allow rule for cluster DNS is mandatory.

What is the difference between the 45-day and 30-day retention numbers in MeitY's cloud guidelines?

They are two separate clauses. As MeitY's Guidelines for Procurement of Cloud Services restate the CSP Empanelment RFP, the provider should not delete any data before 45 days from the expiry of the contract, with the managed service provider ensuring that compliance — an exit hold measured from contract expiry. Separately, the provider should supply a backup solution supporting a retention period of a minimum of 30 days, or as desired by the User Department — an operational backup floor that runs throughout the contract. Fusing them into a single number is a common error in contract responses and one a procurement reader spots immediately.

What does a complete hand-back look like for a containerised estate at contract exit?

The guidelines ask that hand-back leverage standard data formats and give OVF and VHD as examples, "whenever possible". Those are VM-era examples and do not cover a Kubernetes estate on their own. The container-native equivalents are: application images exported as an OCI Image Layout, the specified directory of content-addressable blobs with index.json and oci-layout, which is designed to travel in a tar archive; volume data via the VolumeSnapshot API where the CSI driver supports it, or a filesystem-level copy where it does not; cluster and application state, custom resource definitions included, via a Velero backup of the API objects; and registry contents as a separate deliverable. Ship all of it with a manifest of digests, because ownership of the data rests absolutely with the Government Department, and destruction afterwards must be certified as forensically non-recoverable.

meity empanelmentmeity empanelled cloud service providergovernment cloud india hosting requirementsstqc audit cloud service providergovernment data classification india category a category bpublic sector data localisation india

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.