feat(secrets): teach secrets.subscribe() and link docs in Secrets config guidance#1501
Merged
Merged
Conversation
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Contributor
There was a problem hiding this comment.
Code Review
This pull request updates the scoped secrets access example to read the live accessor and subscribe to secret rotations asynchronously using secrets.subscribe(), replacing the previous static destructuring approach. It also adds links to the Harper secrets documentation in the UI and updates the corresponding tests. The reviewer suggested wrapping the asynchronous subscription loop in a try-catch block to prevent unhandled promise rejections from crashing the application, as this code is intended to be copied and pasted by users.
dawsontoth
added a commit
that referenced
this pull request
Jul 14, 2026
Address review on #1501: the fire-and-forget subscribe loop is copy-paste code, so wrap it in try/catch and console.error the failure (surfacing it rather than swallowing it) so a subscription error can't become an unhandled promise rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dawsontoth
added a commit
to HarperFast/documentation
that referenced
this pull request
Jul 14, 2026
Mirror the studio review fix (HarperFast/studio#1501): the fire-and-forget subscribe loop is copy-paste code, so wrap it in try/catch and console.error the failure so a stream error can't become an unhandled promise rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kriszyp
pushed a commit
to HarperFast/documentation
that referenced
this pull request
Jul 14, 2026
…584) * style(operations-api): apply prettier table alignment Pre-existing format:check violation on the kris/secrets-docs branch; the repo-wide prettier gate must be clean for CI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(security): document secrets change subscription and live scoped accessor Documents harper#1787 (live secret change detection) on the new secrets reference page: - secrets.subscribe(name) — async iterable yielding the current value then every change; shown as read-now + fire-and-forget background subscribe so module load isn't blocked (the practical hot-swap-on-rotation pattern). - Live scoped-tier accessor: a fresh secrets.NAME read reflects the latest value; a destructure is now called out as a point-in-time copy. - Reworked 'Healing after changes' into a per-tier 'How each tier sees a change' table (scoped = live; global/process.env = reload-only) and corrected the 'frozen' accessor description to the read-only live view, with subscribe as a non-enumerable member. Ships in v5.2.0 alongside the rest of the secrets store, so no differential VersionBadge (the page is uniformly 5.2.0 surface). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(security): dedupe the subscribe example's startup rebuild Address review on #584: secrets.subscribe() replays the current value first, so guard on key change to skip the redundant client rebuild on startup, and note that semantic inline. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(security): guard the subscribe example against unhandled rejections Mirror the studio review fix (HarperFast/studio#1501): the fire-and-forget subscribe loop is copy-paste code, so wrap it in try/catch and console.error the failure so a stream error can't become an unhandled promise rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(security): lead with the live accessor; subscription is the exception Per feedback: reading secrets.NAME (undestructured) returns the live value on every read, so most components just use the secret where they need it — e.g. per request inside a resource — and get the current value with no subscription. Only a destructure takes a snapshot. Reframe subscribe() as the case for long-lived objects built from a secret (client/pool/signer) that must be rebuilt on rotation, and make the loader note's per-loader boundary explicit (vm/compartment read live anywhere; native resolves only during load). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
dawsontoth
marked this pull request as ready for review
July 14, 2026 18:57
cb1kenobi
reviewed
Jul 14, 2026
dawsontoth
added a commit
that referenced
this pull request
Jul 14, 2026
Address review on #1501: passing the 'Secrets Docs' link as SecretsManager children put it after Refresh/Add (far right), unlike the sshKeys/certificates pages where the docs link is first. Add a dedicated `docsLink` slot rendered before Refresh/Add and use it from the Secrets config page, matching the convention. The `children` slot (used by the .env editor for its raw-editor button) still renders after Add. Regression test asserts the ordering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ance The inline 'How to read it in your component' guidance on the cluster Secrets config page now shows the live-change API from harper#1787: - Scoped-tier example reads the value immediately, then subscribes in a fire-and-forget background task so module load isn't blocked, guarding on change so the first (current-value) yield doesn't trigger a redundant rebuild. The global/process.env tier stays reload-only (subscribe there is not live), so its example is unchanged. - Outward links to the Harper secrets docs (reference/v5/security/secrets): one contextual link by the code example, one in the config page toolbar. Docs backing the example: HarperFast/documentation#584. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review on #1501: the fire-and-forget subscribe loop is copy-paste code, so wrap it in try/catch and console.error the failure (surfacing it rather than swallowing it) so a subscription error can't become an unhandled promise rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review on #1501: passing the 'Secrets Docs' link as SecretsManager children put it after Refresh/Add (far right), unlike the sshKeys/certificates pages where the docs link is first. Add a dedicated `docsLink` slot rendered before Refresh/Add and use it from the Secrets config page, matching the convention. The `children` slot (used by the .env editor for its raw-editor button) still renders after Add. Regression test asserts the ordering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dawsontoth
force-pushed
the
claude/cluster-secrets-config-guidance-a35de1
branch
from
July 17, 2026 14:08
7f304a5 to
75207c2
Compare
dawsontoth
added a commit
that referenced
this pull request
Jul 17, 2026
Address review on #1501: the fire-and-forget subscribe loop is copy-paste code, so wrap it in try/catch and console.error the failure (surfacing it rather than swallowing it) so a subscription error can't become an unhandled promise rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dawsontoth
added a commit
that referenced
this pull request
Jul 22, 2026
Address review on #1501: the fire-and-forget subscribe loop is copy-paste code, so wrap it in try/catch and console.error the failure (surfacing it rather than swallowing it) so a subscription error can't become an unhandled promise rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dawsontoth
added a commit
that referenced
this pull request
Jul 22, 2026
Address review on #1501: passing the 'Secrets Docs' link as SecretsManager children put it after Refresh/Add (far right), unlike the sshKeys/certificates pages where the docs link is first. Add a dedicated `docsLink` slot rendered before Refresh/Add and use it from the Secrets config page, matching the convention. The `children` slot (used by the .env editor for its raw-editor button) still renders after Add. Regression test asserts the ordering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Enhances the inline "How to read it in your component" guidance on the cluster Secrets config page (the add/edit dialogs) in two ways.
1. Practical
secrets.subscribe()usage (harper#1787)The scoped-tier example now demonstrates the live-change API: read the value immediately, then subscribe in a fire-and-forget background task so module load isn't blocked — with a guard so the first (current-value) yield doesn't trigger a redundant rebuild:
The global /
process.envtier example is unchanged — per harper#1787's tier semantics,subscribethere is reload-only (not live), so a hot-swap example would mislead. Name-aware bracket notation is preserved (secrets['deploy.my-app']).2. Outward documentation links
Both point to
https://docs.harperdb.io/reference/v5/security/secrets(the current canonical docs structure). Plain<a target="_blank" rel="noreferrer">— the repo's dominant external-link pattern — rather than TanStackLink, so the isolated dialog test stays router-free.Docs
The docs page that backs the
subscribe()example is HarperFast/documentation#584 (stacked on the secrets-store docs PR #581). It predated harper#1787, so #584 adds thesecrets.subscribe()section, the live-accessor note, and the per-tier change table.Verification
accessExample.test.tsandSecretsManager.delivery.test.tsxupdated; the delivery test renders the actual dialog DOM and asserts the subscribe line, the change-guard, and the doc-link href. 14/14 secrets tests pass;tsc --noEmit,dprint check, andoxlintall clean.🤖 Generated with Claude Code