Skip to content

feat(plugins): P3c — secret() redaction (D37) + app-config permissions (D36)#105

Merged
aqib-rx merged 3 commits into
feat/plugin-p3b-client-gatingfrom
feat/plugin-p3c-remainder
Jun 17, 2026
Merged

feat(plugins): P3c — secret() redaction (D37) + app-config permissions (D36)#105
aqib-rx merged 3 commits into
feat/plugin-p3b-client-gatingfrom
feat/plugin-p3c-remainder

Conversation

@aqib-rx

@aqib-rx aqib-rx commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Part of the P3 remainder, stacked on P3b. Ships two of the three planned components; D35 (ctx.services elevation) was deferred — see below.

  • D37 — secret() redaction primitive (@nextlyhq/plugin-sdk): Secret<T>/secret()/isSecret that auto-redact via toJSON/toString/util.inspect (→ [redacted]) with explicit .reveal(). Protects logs, NextlyError.logContext, any JSON.stringify. Framework-free; no collection field type (matches D37's "via env/config only").
  • D36 — app-config custom permissions: config.permissions?: PluginPermission[] on NextlyConfig/NextlyServiceConfig (+ sanitize + buildServiceConfig threading); collectCustomPermissions folds app perms (owner app) under the same collision rules as plugin perms. Seeds via the existing P3a boot/post-init wiring.

D35 deferred (honest note)

The combined plan assumed ctx.services.collections was the entry service (params{user,overrideAccess}, body). The real facade is domains/.../collection-service.ts (name, data, context: RequestContext) — no override path, throws on denial, used by the direct API, and RequestContext.user ({id,email,role,permissions}) is incompatible with AuthUser. Real {as:'system'} needs additive overrideAccess threading through the shared facade + reconciling 3 user types — a design-sensitive core change, not a pure wrapper. The wrong-shaped ServiceOpts/translator work was reverted; D35 gets its own brainstorm. So P3 is not fully complete — D35 remains.

Test Plan

  • nextly unit baseline unchanged (405 failed / 32 files) → zero new failures; +5 new passing (secret 6 in sdk; config 2 + collector 3 in nextly)
  • SDK + nextly build + check-types clean
  • form-builder 16/16 unchanged

Stacked on feat/plugin-p3b-client-gating; retarget to feat/plugin-platform after the earlier P3 PRs merge. No changeset.

@github-actions

Copy link
Copy Markdown
Contributor

PR title fails Conventional Commits check

Unknown scope "plugins" found in pull request title "feat(plugins): P3c — secret() redaction (D37) + app-config permissions (D36)". Scope must match one of: nextly, admin, client, ui, adapter-postgres, adapter-mysql, adapter-sqlite, adapter-drizzle, storage-s3, storage-vercel-blob, storage-uploadthing, plugin-form-builder, create-nextly-app, eslint-config, prettier-config, tsconfig, playground, root, ci, docs, deps, release.

Examples of valid titles:

  • feat(admin): add role manager dialog
  • fix(adapter-postgres): handle connection pool exhaustion
  • chore(deps): bump zod to 4.2.0

@github-actions github-actions Bot added scope: core nextly scope: plugin @nextlyhq/plugin-* packages labels Jun 17, 2026
@aqib-rx aqib-rx merged commit fd55a28 into feat/plugin-p3b-client-gating Jun 17, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: core nextly scope: plugin @nextlyhq/plugin-* packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant