Skip to content

src,permission: emit dc messages from C++ and use --permission-audit #61869

Open
RafaelGSS wants to merge 6 commits intonodejs:mainfrom
RafaelGSS:implement-dc-cpp-side
Open

src,permission: emit dc messages from C++ and use --permission-audit #61869
RafaelGSS wants to merge 6 commits intonodejs:mainfrom
RafaelGSS:implement-dc-cpp-side

Conversation

@RafaelGSS
Copy link
Member

This PR supersedes #60578.

src,permission: add --permission-audit

Add --permission-audit flag that enables the permission model in
warning-only mode. Instead of throwing ERR_ACCESS_DENIED, it emits
a message via diagnostics channel and allows the operation to
continue.

Publish permission check results to per-scope diagnostics channels
(e.g., node:permission-model:fs) so users can observe permission
decisions at runtime via diagnostics_channel.

Refs: https://github.com/nodejs/node/issues/59935

src: add C++ support for diagnostics channels

Add a C++ API for diagnostics channels that allows native code to check
for subscribers and publish messages without unnecessary JS boundary
crossings. Uses a shared AliasedUint32Array buffer between C++ and JS
to track subscriber counts per channel, enabling a fast inline check
(HasSubscribers) that reads the buffer directly.

PTAL @joyeecheung @Qard

Add a C++ API for diagnostics channels that allows native code to check
for subscribers and publish messages without unnecessary JS boundary
crossings. Uses a shared AliasedUint32Array buffer between C++ and JS
to track subscriber counts per channel, enabling a fast inline check
(HasSubscribers) that reads the buffer directly.
Add --permission-audit flag that enables the permission model in
warning-only mode. Instead of throwing ERR_ACCESS_DENIED, it emits
a message via diagnostics channel and allows the operation to
continue.

Publish permission check results to per-scope diagnostics channels
(e.g., node:permission-model:fs) so users can observe permission
decisions at runtime via diagnostics_channel.

Refs: nodejs#59935
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/config
  • @nodejs/gyp
  • @nodejs/security-wg
  • @nodejs/startup

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Feb 17, 2026
@RafaelGSS RafaelGSS requested a review from Qard February 17, 2026 19:47
@RafaelGSS RafaelGSS added semver-minor PRs that contain new features and should be released in the next minor version. permission Issues and PRs related to the Permission Model labels Feb 17, 2026
@RafaelGSS RafaelGSS added the commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. label Feb 17, 2026
Copy link
Member

@Qard Qard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool! Not going to block on it, but it would be ideal if we could have a more direct ObjectWrap pattern to link native channels to their JS counterpart and do publishes more directly rather than through this lookup table and callback doing a channel lookup on every publish.

One thing that may need some additional thought either way is what to do if a publish call happens at a point where it's not valid to call into JS at that exact time. What do we do in that situation? Panic? Schedule for next tick?

Comment on lines 632 to 635
dc_binding.setPublishCallback((name, message) => {
const ch = dc.channel(name);
if (ch.hasSubscribers) ch.publish(message);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge fan of needing to call dc.channel(...) within the publish hot-path.

Was there some reason you didn't go for just having the C++ Channel type use ObjectWrap::Wrap(...) to wrap the actual channel object itself? I know we might not be able to do so immediately as the C++ channels might be initialized before we can actually get into JS, but we can late-bind, right?

Perhaps rather than a setPublishCallback we could have something like:

dc_binding.linkNativeChannel((name) => {
  return dc.channel(name);
});

When that is first called it'd immediately wrap all not-yet-wrapped native channels around their JS equivalent and then store the callback to do so for any future native channels.

Copy link
Member Author

@RafaelGSS RafaelGSS Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could check if there are pending when linkNativeChannel is called. Pushing a commit shortly.

The reason I didn't use the ObjectWrap was due to a much larger refactor that would be necessary on diagnostics_channel js, and I was afraid of breaking/slowing the current status quo.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL 127b87a

Comment on lines 220 to 221
diagnostics_channel::Channel ch =
diagnostics_channel::Channel::Get(env, channel_name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do this ahead of time in Permission::Permission() or something like that to more closely mirror the object-reuse pattern we have on the JS side?

I care less about the perf in this specific case and more thinking about if we are able to support that as a pattern as I would ideally like to start using this to add channels to other parts of native code too. 🤔

@Qard
Copy link
Member

Qard commented Feb 17, 2026

cc @bengl You may also have opinions on the diagnostics_channel implementation in here.

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

❌ Patch coverage is 85.05155% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.71%. Comparing base (4a13a62) to head (80bbdc7).
⚠️ Report is 24 commits behind head on main.

Files with missing lines Patch % Lines
src/node_diagnostics_channel.cc 87.62% 1 Missing and 11 partials ⚠️
src/permission/permission.cc 80.39% 6 Missing and 4 partials ⚠️
src/env.cc 0.00% 2 Missing and 2 partials ⚠️
lib/diagnostics_channel.js 88.88% 2 Missing ⚠️
src/node_diagnostics_channel.h 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #61869      +/-   ##
==========================================
- Coverage   89.76%   89.71%   -0.05%     
==========================================
  Files         675      677       +2     
  Lines      204674   204990     +316     
  Branches    39330    39378      +48     
==========================================
+ Hits       183716   183904     +188     
- Misses      13235    13301      +66     
- Partials     7723     7785      +62     
Files with missing lines Coverage Δ
lib/internal/process/pre_execution.js 97.32% <100.00%> (+1.35%) ⬆️
src/node_binding.cc 82.74% <ø> (ø)
src/node_external_reference.h 100.00% <ø> (ø)
src/node_options.cc 76.30% <100.00%> (+0.02%) ⬆️
src/node_options.h 97.90% <100.00%> (+0.01%) ⬆️
src/node_snapshotable.cc 73.01% <ø> (+0.07%) ⬆️
src/permission/permission.h 100.00% <100.00%> (+20.00%) ⬆️
src/node_diagnostics_channel.h 75.00% <75.00%> (ø)
lib/diagnostics_channel.js 98.69% <88.88%> (-0.41%) ⬇️
src/env.cc 85.19% <0.00%> (-0.05%) ⬇️
... and 2 more

... and 67 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@RafaelGSS RafaelGSS removed the commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. label Feb 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. permission Issues and PRs related to the Permission Model semver-minor PRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants