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.
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.
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.
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.
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"
}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.
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.