Skip to main content

NIS2 compliance at the API gateway: the controls regulated enterprises need

NIS2 Article 21 compliance for regulated enterprises: how to configure RBAC, access control, audit trail, and incident detection at the API gateway layer.

  • compliance
  • security
  • rbac
  • audit
  • regulated-industries
Zerq team

NIS2 compliance at the API gateway layer is no longer a planning item for regulated enterprises. The EU's Network and Information Security Directive (Directive 2022/2555, known as NIS2) is in full enforcement across member states, with national supervisory authorities actively auditing essential services and important entities in banking, healthcare, energy, transport, and digital infrastructure. Article 21 of the directive requires documented risk management measures: access controls with separation of duties, appropriate authentication, encryption of sensitive data, comprehensive logging, and incident detection capability. For most platform teams, those requirements land on your API gateway first.

The gap most organisations discover when preparing for a NIS2 supervisory review is not a capability gap. It is an evidence gap. You have rate limits. You have authentication. You have some logs scattered across multiple systems. But can you prove to an auditor that only authorised, authenticated identities made configuration changes to your API platform in the last twelve months? Can you show which person updated a rate limit policy on a specific date, from which IP address, and what value it was changed to? Can you isolate the complete audit trail for your API infrastructure without querying five separate tools and then reconciling the results?

That is where the NIS2 compliance API gateway conversation begins, and where most standard gateway setups start to break down.

Why existing approaches fail

The structural problem with most API gateway setups is that audit evidence and API configuration are managed in different systems. AWS API Gateway routes traffic reliably, but its audit records live in CloudTrail: a separate service requiring separate IAM configuration, separate query access, and separate retention policies. Assembling a complete picture of who changed an API configuration and when requires cross-referencing two distinct AWS services with different data models and different access controls.

Azure APIM has the same split: diagnostic events flow to Azure Monitor or Log Analytics, not into the platform itself. Walking through the Azure toolchain to produce a timestamped, attributed record of a specific policy change is possible but not built into the product in the way a compliance team expects. Kong's audit logging is gated behind the Enterprise license tier and is not available in the standard deployment most teams start with. Apigee's audit infrastructure is part of Google Cloud's centralised audit system, which means your compliance records live in Google's control plane rather than your own infrastructure.

None of these are insurmountable problems. But they all require assembling a patchwork of tools to satisfy Article 21 controls that an API gateway should handle natively and that must be demonstrated as a coherent system to a regulator. The regulation does not care that your audit records are split across CloudTrail, CloudWatch, and a SIEM you spent months configuring to stitch together. It cares that you have complete, attributable, tamper-evident records of access and configuration changes that you can produce on demand.

NIS2 Article 21 and the API gateway layer

Article 21 requires risk management measures across five areas that apply directly to API infrastructure: access control, authentication, encryption, logging, and incident detection. Here is how each maps to a specific gateway control.

Access control and separation of duties

Article 21 requires that access to network and information systems follows least-privilege principles and that the people reviewing security records are not the same people who can change security configuration. Zerq's security model enforces this at the management layer through four distinct roles validated from OIDC claims on every management request.

The four management roles are:

RoleWhat it can do
viewerRead-only access to all resources: collections, proxies, clients, policies, request logs
modifier (mapped via OIDC_MODIFIER_ROLES)Create, update, and delete all managed resources
auditorRead-only access to audit logs only; cannot view or modify any other resource
adminAll operations, including deletion of log entries

The auditor role is the separation of duties control NIS2 auditors look for. A compliance team member or external auditor with only the auditor role can review the complete audit trail for any time period (who changed what, when, from which IP) but cannot touch any API configuration. The management API enforces this at the backend level. The UI reflects it: an auditor sees the Audit Logs sidebar entry and nothing else that could modify the platform.

For API consumers, every client in Zerq has a profile that defines which collections it can call, which HTTP methods it is permitted to use, which IP addresses are allowed, and how many requests per interval it can send. These controls are enforced on every gateway request, independently of the application layer.

Configuring OIDC and RBAC: a complete example

The following configuration maps your enterprise IdP groups to Zerq's permission tiers. Adjust the group names to match what your IdP actually issues.

# backend/.env: management API OIDC authentication

# Enable OIDC-based management auth
OIDC_ENABLED=true
OIDC_ISSUER_URL=https://auth.example.com/realms/platform
OIDC_AUDIENCE=zerq-management

# Path to the roles claim within the OIDC JWT
# In Keycloak: realm_access.roles or a custom claim
# In Entra ID: roles or groups
OIDC_ROLE_CLAIM_PATH=realm_access.roles

# Cache validated tokens to reduce IdP request load
OIDC_CACHE_TTL=60

# Map your IdP group names to Zerq permission tiers
OIDC_VIEWER_ROLES=platform-viewer,platform-dev
OIDC_MODIFIER_ROLES=platform-engineer,platform-ops
OIDC_AUDITOR_ROLES=compliance-team,security-auditor,external-auditor
OIDC_ADMIN_ROLES=platform-admin

The frontend management UI reads its own role-mapping configuration separately and must match the backend:

# frontend/.env: management UI role gates

NEXT_PUBLIC_VIEWER_ROLES=platform-viewer,platform-dev
NEXT_PUBLIC_MODIFIER_ROLES=platform-engineer,platform-ops
NEXT_PUBLIC_AUDITOR_ROLES=compliance-team,security-auditor,external-auditor
NEXT_PUBLIC_ADMIN_ROLES=platform-admin

# OIDC client configuration for the UI session
OIDC_ISSUER_URL=https://auth.example.com/realms/platform
OIDC_CLIENT_ID=zerq-frontend
OIDC_CLIENT_SECRET=$ZERQ_FRONTEND_OIDC_SECRET

Keeping these two sets synchronised is critical for correctness. If they diverge (after an IdP group rename, for example), the UI may display actions that the backend will reject, or hide actions the backend would permit. After any IdP group change, test one route from each tier to confirm the mapping is intact before considering the change complete.

Granting your compliance team audit access

Here is the step-by-step sequence for giving a compliance team member or external auditor read-only access to the Zerq audit trail:

  1. In your IdP (Keycloak, Entra ID, Okta, or similar), create a group named compliance-team, or reuse the group name you have already defined for your audit function.
  2. Add the auditor's identity to that group and ensure MFA is enforced at the IdP level for that group. NIS2 Article 21 specifically requires appropriate authentication for access to management interfaces; MFA at the IdP satisfies this for management UI access.
  3. Confirm the deployed backend has OIDC_AUDITOR_ROLES=compliance-team (or the equivalent for your chosen group name). No gateway restart is needed if OIDC is already enabled; the role is resolved from each incoming JWT.
  4. Ask the auditor to sign in to the Zerq management UI using their enterprise SSO credentials. They will see the Audit Logs entry in the sidebar. No other navigation items are visible or accessible with this role.
  5. The auditor navigates to Audit Logs, sets the date range covering the review period, and filters by resource type and action to scope the review. For a credential rotation audit: resource type credential, action UPDATE. For rate limit changes: resource type policy, action UPDATE.
  6. Each log entry shows the full attribution record: actor ID, actor type, action, affected resource, IP address, timestamp, request body (what value was submitted), and response status (whether the change succeeded).

The auditor can search, filter, and export from the UI, or query the audit API directly:

# Export all policy changes in H1 2026 (requires auditor-role token)
curl -H "Authorization: Bearer $AUDITOR_TOKEN" \
  "https://management.example.com/api/v1/audit/logs?from=2026-01-01&to=2026-06-30" \
  | jq '.[] | select(.resource_type == "policy")'

This produces structured JSON directly compatible with Splunk, Elastic SIEM, Microsoft Sentinel, and any SIEM accepting structured JSON input.

Encryption controls

Article 21 requires appropriate cryptographic measures. Zerq handles encryption at two distinct layers: at rest and in transit, independently of each other.

All sensitive credential values stored by the gateway (API keys, connection strings, OAuth2 client secrets, certificate material) are encrypted with AES-256 before storage in MongoDB. The key is provided via the ENCRYPTION_KEY environment variable at runtime and is never written to the database. A MongoDB backup without the encryption key is ciphertext that cannot be used:

# backend/.env: encryption at rest
ENCRYPTION_KEY=<your-32-byte-random-key>  # never store this in the database or git

For transit, all gateway and management traffic must be served over TLS 1.2 or higher. For machine-to-machine API consumers in regulated environments, mTLS provides cryptographic client identity at the TLS handshake: no shared secret is ever transmitted over the network. This is the strongest authentication option for high-assurance API clients and is what open banking regulations such as PSD2 require for TPP authentication.

For credential values that should not appear in the database at all, Zerq supports referencing environment variables using $ENV_VAR_NAME syntax in credential fields. The reference string is stored; the actual value is resolved at runtime from the gateway's environment, which can be populated from HashiCorp Vault, AWS Secrets Manager, or Kubernetes secrets.

Audit logging: what goes into the record

Zerq's observability layer records two distinct log types: request logs for API traffic and audit logs for management configuration changes. Enable audit logging with a single backend environment variable:

AUDIT_ENABLED=true

Every audit log entry captures:

FieldWhat it gives a NIS2 auditor
TimestampExact time of the action in UTC
Actor IDThe OIDC subject identifying who made the change
Actor typeWhether this was a user, service, or system action
ActionCREATE, UPDATE, or DELETE
Resource typeWhat was affected: collection, proxy, client, policy, credential
Resource IDThe specific resource identifier
IP addressSource IP of the management request
User agentBrowser version or API client identifier
Request bodyThe full payload submitted, including the new value being set
Response statusHTTP status showing whether the change succeeded or was rejected

The Request body field is what lets you reconstruct the before and after state of any configuration change without maintaining a separate version control system. If a rate limit was changed from 100 requests per minute to 500, the audit log for that UPDATE on the policy resource contains the full payload including the new value. The previous value is visible in the log entry immediately before it.

Audit records are stored in your own MongoDB instance and are never transmitted to Zerq's systems. Set retention to meet your regulatory requirement. Most financial and healthcare regulations require 5 to 7 years:

# Log and audit retention is controlled via MongoDB TTL index settings on the
# audit and request log collections. Set the TTL to match your compliance period.
# Example: 2555 days for a 7-year retention in a financial services context.

Incident detection at the API layer

Article 21 requires the ability to detect incidents. At the API gateway layer, the detection signals come from request logs. Zerq logs every API call with the fields needed to identify anomalous patterns: HTTP status, latency, client ID, profile ID, collection, client IP, and full request and response bodies.

A repeating pattern of 401 responses from a single client_id indicates a compromised or rotated credential that has not been updated in the caller. A burst of 403 responses from a client suggests an attempt to reach collections that client is not permitted to access, a signal worth investigating whether the client is an application or an AI agent. Unusual latency on specific backend paths points to upstream service degradation before it becomes visible to end users.

Request log filters are URL-addressable, so you can bookmark a view filtered by client, status code class, and time window, then share it with a colleague who sees exactly the same results. Zerq exposes Prometheus metrics that feed into alerting rules on 4xx rate spikes or unusual volume from specific clients, producing the incident detection evidence Article 21 requires.

NIS2 Article 21 controls: an API gateway checklist

Use this to assess where your current gateway configuration stands.

Access control

  • Every management user has an IdP-backed identity with no shared admin credentials
  • Separation of duties is enforced: the people reviewing audit records cannot modify platform configuration
  • API consumers are scoped to the minimum collections and HTTP methods their use case requires
  • IP allowlists are configured on profiles for high-assurance machine-to-machine clients

Authentication

  • Management access uses OIDC with MFA enforced at the IdP level
  • Machine-to-machine clients in regulated flows use mTLS for cryptographic identity
  • Token rotation is scheduled or can be triggered immediately on suspected compromise
  • Sensitive credential values are encrypted at rest with a key stored outside the database

Encryption

  • All gateway and management traffic is served over TLS 1.2 or higher
  • MongoDB and Redis connections use TLS
  • ENCRYPTION_KEY is provisioned from a secrets manager, not hardcoded in config files

Logging

  • AUDIT_ENABLED=true is set in the backend configuration
  • Audit records include actor identity, timestamp, source IP, and change payload
  • Retention period matches your regulatory requirement (typically 5 to 7 years for financial services)
  • Request logs are retained and accessible for the incident investigation window your regulator requires
  • Audit log export to SIEM is tested and documented

Incident detection

  • You can produce a time-bounded, actor-scoped change record within 24 hours of a request
  • Alerts are configured on 4xx and 5xx rate spikes and unusual client traffic patterns
  • You have a documented procedure for revoking a compromised credential (rotating or disabling the profile) and can execute it in under an hour

What this looks like in practice

A European bank preparing for its first NIS2 supervisory review ran its open banking API gateway entirely on-premises, with no configuration or audit data leaving the bank's infrastructure. The platform team assigned the compliance-team IdP group to the Zerq auditor role. Their external auditor and internal compliance officer both received SSO access through that group, with MFA enforced at the IdP. Neither could modify any gateway configuration.

During the review, the supervisor asked for a record of all credential rotation events for the API gateway in the previous twelve months. The compliance officer filtered the audit log by resource type credential and action UPDATE, set the date range, and exported the results in under five minutes. Every rotation event showed the actor's identity, the exact timestamp, and the source IP. For the access control review, they produced a filtered view of all policy changes with full attribution in the same interface.

The bank passed the authentication control assessment by demonstrating mTLS between their TPP-facing gateway profiles and presenting the profile configuration showing the CA certificate against which TPP certificates are validated. The incident detection evidence came from Prometheus alert rules against 4xx spikes, linked to request log entries showing the specific client IDs and IP addresses that triggered each alert. Everything came from the same platform, with no cross-system reconciliation required.

The key advantage

NIS2 does not require you to build a new compliance system. It requires your existing API infrastructure to be auditable by design: role-based access with documented separation of duties, audit logs that capture actor identity and change payload, credential encryption that survives a database breach, and request logs that let you reconstruct any incident. Zerq's architecture is built to produce that evidence without adding tools, without routing data to a third-party control plane, and without discovering the gaps three weeks before your audit deadline.


Zerq is an enterprise API gateway built for regulated industries — one platform for API management, AI agent access, compliance audit, and developer portal, running entirely in your own infrastructure. See how it works or request a demo to walk through your specific requirements.