heygrc
NIS 2 in code

NIS 2, reviewed in the pull request.

The NIS 2 Directive sets a baseline of cybersecurity duties for essential and important entities across the EU. Its core, Article 21(2), reads almost like an engineering checklist: supply-chain security, secure development and vulnerability handling, cryptography, access control, multi-factor authentication. Most of those are satisfied or broken by code, which makes the pull request the natural place to check them.

The measures are unusually concrete

A directive that names the engineering controls.

Most regulations stay at the level of principles and leave the controls to you. NIS 2 is more specific: Article 21(2) lists the measures by name, and several of them, cryptography, access control, multi-factor authentication, vulnerability handling, secure development, map directly onto code. That specificity is what makes NIS 2 reviewable at the diff. heygrc reads each change against the listed measures and cites the exact point, so a NIS 2 gap is a review comment rather than a finding in a supervisory inspection.

Measures that surface in a diff

The Art. 21(2) measures a review can actually catch.

Each row is a real Art. 21(2) point and the kind of change that trips it. heygrc cites the measure on the finding, not a vague security note.

  • Art. 21(2)(d)supply chain security

    A new dependency or third-party component is added with no integrity check, pinned version, or provenance, widening the supply-chain surface.

  • Art. 21(2)(e)secure development and vulnerability handling

    A security lint or scan is disabled to make a change pass, or a known-vulnerable pattern (unsanitised input, unsafe deserialisation) is introduced.

  • Art. 21(2)(f)effectiveness of measures

    A test, check, or assertion that demonstrated a security measure worked is removed, so there is no longer evidence the measure is effective.

  • Art. 21(2)(g)cyber hygiene basics

    An insecure default ships: a public bucket, a wildcard CORS policy, debug mode left on, a default credential left in place.

  • Art. 21(2)(h)cryptography and encryption

    A TLS floor drops, a weak hash or cipher is introduced, or a key lands hardcoded instead of in a managed secret store.

  • Art. 21(2)(i)access control and asset management

    A role broadens, an authorization check is dropped, or a path reaches an asset or scope it previously could not.

  • Art. 21(2)(j)multi-factor authentication

    An MFA check is skipped on a sensitive path, or a session is given a far longer lifetime that effectively weakens authentication.

Worked example

A skipped check that weakens Art. 21(2)(j).

A pull request adds a fast path for an internal admin tool and skips the second-factor step to make local testing easier. The bypass ships to production along with the feature.

auth/admin.ts+1 −0
export function requireAdmin(session: Session) {
+  if (session.internal) return true  // skip MFA for internal tools  if (!session.mfaVerified) throw new Forbidden()
  return session.role === "admin"
}
heygrcNIS 2 Art. 21(2)(j)

This grants admin access to any session marked internal without the second factor. Art. 21(2)(j) expects multi-factor authentication on access like this, and 21(2)(i) covers the access control it bypasses. Keep the MFA check on the admin path and solve the local-testing need with a test fixture rather than a production bypass.

What this is, and is not

A review, not a compliance sign-off.

heygrc flags changes that touch a NIS 2 measure and cites the point so the fix happens in the pull request. It does not register your entity, file your incident notifications, or carry the management-body accountability the directive assigns. It catches the change early so a security measure holds in code review instead of failing under inspection. heygrc is in early access.