Skip to content

fix(web): keep the private ingest key out of onboarding snippets and the agent prompt - #1182

Closed
JeremyFunk wants to merge 2 commits into
mainfrom
fix/onboard-prompt-private-key-env
Closed

JeremyFunk wants to merge 2 commits into
mainfrom
fix/onboard-prompt-private-key-env

Conversation

@JeremyFunk

@JeremyFunk JeremyFunk commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Brings the in-product onboarding in line with the maple-onboard skill's key rules (#1115): servers read the private key from MAPLE_INGEST_KEY, browser/mobile code inlines the public key, and the private key never goes into a prompt pasted into an AI tool.

  • Instrument snippets (sdk-snippets.ts): Next.js, Node, Python, Go and the generic OTel env snippet read MAPLE_INGEST_KEY instead of inlining the public key. When it is unset they log MAPLE_INGEST_KEY is not set; Maple telemetry export is disabled and skip the Maple exporter: no throw, no exit, no Bearer undefined. The shell snippet sets OTEL_SDK_DISABLED=true in that case. The Effect snippet already read the env var; its comment now names the private key.
  • Claude Code prompt (onboard-skill.ts): carries the endpoint, the public key (labelled for browser and mobile code), and a line saying the user sets MAPLE_INGEST_KEY themselves. With no public key loaded, the key line is dropped so the skill falls back to MAPLE_TEST, instead of inlining a <your-ingest-key> placeholder.
  • Guided setup (guided-setup.tsx): the Claude Code tab tells the user to set MAPLE_INGEST_KEY in .env and their deployment secrets. The checklist's credentials column reuses ConnectCredentials (endpoint + public + private key, admin fallback), replacing the single "API key" field that showed the public key. The instrument block no longer carries a key, so it drops the replay block; the prompt block keeps it.

Decisions:

  • Missing key → warn and skip export rather than fail fast, per the agreed rule that instrumentation never crashes or blocks the app.
  • Out of scope: the infra install modal (install-modal.tsx) still puts the private key on the helm/docker command lines; that is a separate collector flow.

Tests: onboard-skill.test.ts, guided-setup.browser.test.tsx updated; new sdk-snippets.test.ts asserts every snippet reads MAPLE_INGEST_KEY and inlines no key.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • New Features
    • Setup instructions now distinguish public keys for browser and mobile code from private keys used by server-side integrations. Server examples read the private key from MAPLE_INGEST_KEY, which should be set in your environment or deployment secrets.
    • SDK quick-start examples now use environment-based private keys for authorization. When a key is missing, examples warn or skip telemetry setup rather than including a placeholder key.

…the agent prompt

Server snippets read MAPLE_INGEST_KEY and skip export with one warning when it
is unset. The Claude Code prompt carries only the endpoint and public key and
tells the agent the user sets MAPLE_INGEST_KEY themselves, matching the
maple-onboard skill. The checklist's credentials column shows both keys.
@maple-review-bot

maple-review-bot Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Maple review

🟡 Confidence 3/5 · needs attention
The snippet and prompt key handling now runs opposite to skills/maple-onboard/SKILL.md, which ships in this repo and is never updated here.
quality 90/100 · 1 warning · tests covered · risk medium

Moves the onboarding instrument snippets and the Claude Code prompt off the inlined ingest key onto MAPLE_INGEST_KEY, and swaps the checklist's single key field for the shared credentials component. Web tests cover the new snippets; one consistency problem remains against the skill this prompt invokes.

  • Instrument snippets read MAPLE_INGEST_KEY and skip the Maple exporter when it is unset
  • onboardSkillPrompt carries only the public key, labelled for browser and mobile code
  • Guided setup reuses ConnectCredentials for the endpoint and both keys
  • New sdk-snippets.test.ts asserts no snippet inlines a key

Findings

🟠 Warning · F1 · Prompt sends servers to MAPLE_INGEST_KEY, but the shipped skill says inline the key

convention · apps/web/src/components/ingest/onboard-skill.ts:12

The prompt tells the agent server code reads the private key from MAPLE_INGEST_KEY set by the user, and all six instrument snippets assert MAPLE_INGEST_KEY is set, warn and skip the exporter. The shipped rule the prompt invokes, skills/maple-onboard/SKILL.md:34 and :185, still says the ingest key is inlined in the bootstrap source and lists env-var indirection as a failure mode ("env-var indirection just adds deploy-time failure modes for no gain"), and its public-key path (:43) inlines it in every bootstrap file, servers included. Until #1115 lands with these snippets, the agent gets one instruction from the prompt and the opposite from the skill it must read, so a user who pastes the prompt can still end up with the key inlined in server source.

Land the skill change (`skills/maple-onboard/SKILL.md` Step 0 and Hard rules) in the same release as these snippets, or keep the prompt's server line only once that rule is on main.
🤖 Prompt to fix this finding with an AI agent
Findings from an automated review of commit 7665f4fabeed3b7f122742c620034be6998414ec. Verify each one against the current code before changing anything, fix only those that still apply, and keep each fix to the lines it names.

---

F1 · Warning · convention · apps/web/src/components/ingest/onboard-skill.ts:12
Prompt sends servers to `MAPLE_INGEST_KEY`, but the shipped skill says inline the key
The prompt tells the agent server code reads the private key from `MAPLE_INGEST_KEY` set by the user, and all six instrument snippets assert `MAPLE_INGEST_KEY` is set, warn and skip the exporter. The shipped rule the prompt invokes, `skills/maple-onboard/SKILL.md:34` and `:185`, still says the ingest key is inlined in the bootstrap source and lists env-var indirection as a failure mode ("env-var indirection just adds deploy-time failure modes for no gain"), and its public-key path (`:43`) inlines it in every bootstrap file, servers included. Until #1115 lands with these snippets, the agent gets one instruction from the prompt and the opposite from the skill it must read, so a user who pastes the prompt can still end up with the key inlined in server source.
Suggested fix: Land the skill change (`skills/maple-onboard/SKILL.md` Step 0 and Hard rules) in the same release as these snippets, or keep the prompt's server line only once that rule is on main.
What was checked
  • Python and Go missing-key branches stay valid on their happy and empty paths (sdk-snippets.ts:105-113, :151-160)
  • Dropped REPLAY_BLOCK_CLASS on the instrument tab is safe: the snippet no longer holds a key (guided-setup.tsx:194-197)
  • ConnectCredentials renders the private key through the same masked input the settings page uses (copyable-field.tsx:41-45)

7665f4f · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: bfe626cb-3a99-4e4c-8341-279d698167ef

📥 Commits

Reviewing files that changed from the base of the PR and between 1a03fa7 and 1f8b681.

📒 Files selected for processing (6)
  • apps/web/src/components/ingest/guided-setup.browser.test.tsx
  • apps/web/src/components/ingest/guided-setup.tsx
  • apps/web/src/components/ingest/onboard-skill.test.ts
  • apps/web/src/components/ingest/onboard-skill.ts
  • apps/web/src/components/quick-start/sdk-snippets.test.ts
  • apps/web/src/components/quick-start/sdk-snippets.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

Guided onboarding and quick-start server snippets now distinguish the public ingest key from the private MAPLE_INGEST_KEY. Server exporters use the environment value for Bearer authorization and handle missing keys with warnings or skipped or disabled export paths. Tests check prompt content and snippet key handling.

Changes

Ingest key handling

Layer / File(s) Summary
Guided setup and onboarding prompts
apps/web/src/components/ingest/onboard-skill.ts, apps/web/src/components/ingest/onboard-skill.test.ts, apps/web/src/components/ingest/guided-setup.tsx, apps/web/src/components/ingest/guided-setup.browser.test.tsx
The onboarding prompt includes the public key when present and tells users to configure MAPLE_INGEST_KEY for server code. Guided setup no longer inserts the API key into instrumentation snippets and renders ConnectCredentials when the credentials column is shown.
Environment-backed quick-start snippets
apps/web/src/components/quick-start/sdk-snippets.ts, apps/web/src/components/quick-start/sdk-snippets.test.ts
The server snippets read MAPLE_INGEST_KEY for Bearer authorization. When the key is missing, snippets warn, skip export, or disable the SDK. Go logs exporter-construction errors instead of terminating.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: makisuo

Merge Risk: 🟡 Moderate · up to 1f8b6

Server snippets now use environment-backed credentials, but the onboarding skill still directs users to inline keys. Align the skill and prompt before merging so generated integrations follow consistent credential-handling rules.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 1f8b6

The change reduces embedded credential exposure and preserves organization-admin access controls. However, the new environment-based setup guidance conflicts with the companion installation instructions, leaving the intended credential separation inconsistent.

Retained concerns

  • Low · security · observed: The new environment-only server credential contract conflicts with the bundled onboarding skill, which still directs agents to inline the public key on servers and avoid environment configuration. Base guidance and the skill agreed on embedded keys; head introduces contradictory instructions. This leaves enforcement of the intended credential separation dependent on how the agent resolves the conflict, rather than a coherent installation contract. It does not establish that a private key was leaked.
Security review details

Security Blast Radius

  • inferred — The added credential-display exposure is bounded by the current organization's admin authorization. The companion skill prescribes installation across every runnable service in the user's repository, so inconsistent credential guidance can propagate beyond a single example or service.

Trust Boundaries and Controls

  • inferred — The new credential fields lack a local replay-block wrapper, but revealed secrets remain input values. Dashboard privacy documentation specifies input masking, and the recorder forwards that masking configuration to rrweb. This is substantial counterevidence to a replay-leak claim; the generated public-key text separately retains its replay-block wrapper. The effective dashboard recorder layer and a revealed-field recording were not directly validated.

Resilience and Maintainability Implications

  • observed — The existing retained-query identity includes the active organization. Organization changes invalidate cached authorization, and authorization resolution fails closed when an established organization changes during an asynchronous request. These controls remain available to the new credentials consumer; full component recovery behavior was not exercised.

Hardening Proposals

  • proposed — Align the companion skill and generated setup instructions around one credential policy, including missing-key behavior. This would make server-side private-key handling a consistent installation contract rather than leaving agents to resolve contradictory guidance.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: preventing the private ingest key from appearing in onboarding snippets and the agent prompt.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@maple-review-bot maple-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 inline note from Maple's review. The score and summary are in the review comment above.

`My ingest endpoint is ${ingestUrl}.`,
`My ingest key is ${ingestKey || "<your-ingest-key>"}.`,
...(publicKey ? [`My public ingest key for browser and mobile code is ${publicKey}.`] : []),
"Server code reads my private key from MAPLE_INGEST_KEY, which I set in my environment or .env myself.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

Prompt sends servers to MAPLE_INGEST_KEY, but the shipped skill says inline the key

F1 · Warning · convention

The prompt tells the agent server code reads the private key from MAPLE_INGEST_KEY set by the user, and all six instrument snippets assert MAPLE_INGEST_KEY is set, warn and skip the exporter. The shipped rule the prompt invokes, skills/maple-onboard/SKILL.md:34 and :185, still says the ingest key is inlined in the bootstrap source and lists env-var indirection as a failure mode ("env-var indirection just adds deploy-time failure modes for no gain"), and its public-key path (:43) inlines it in every bootstrap file, servers included. Until #1115 lands with these snippets, the agent gets one instruction from the prompt and the opposite from the skill it must read, so a user who pastes the prompt can still end up with the key inlined in server source.

Land the skill change (`skills/maple-onboard/SKILL.md` Step 0 and Hard rules) in the same release as these snippets, or keep the prompt's server line only once that rule is on main.
🤖 Prompt to fix with an AI agent
In `apps/web/src/components/ingest/onboard-skill.ts:12`: Prompt sends servers to `MAPLE_INGEST_KEY`, but the shipped skill says inline the key.

The prompt tells the agent server code reads the private key from `MAPLE_INGEST_KEY` set by the user, and all six instrument snippets assert `MAPLE_INGEST_KEY` is set, warn and skip the exporter. The shipped rule the prompt invokes, `skills/maple-onboard/SKILL.md:34` and `:185`, still says the ingest key is inlined in the bootstrap source and lists env-var indirection as a failure mode ("env-var indirection just adds deploy-time failure modes for no gain"), and its public-key path (`:43`) inlines it in every bootstrap file, servers included. Until #1115 lands with these snippets, the agent gets one instruction from the prompt and the opposite from the skill it must read, so a user who pastes the prompt can still end up with the key inlined in server source.

Suggested fix: Land the skill change (`skills/maple-onboard/SKILL.md` Step 0 and Hard rules) in the same release as these snippets, or keep the prompt's server line only once that rule is on main.

Verify the problem exists at that location before changing it, and keep the fix to those lines.

@maple-review-bot

maple-review-bot Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Maple review

🟡 Confidence 3/5 · needs attention
The only change since the last review is test code that still fails if a key reaches a snippet; the open prompt-versus-skill mismatch (F1) is untouched.
quality 90/100 · 1 warning · tests covered · risk medium

The head commit drops the credentials column from the guided-setup browser tests so they render without a query provider. The snippet and prompt changes it guards were already reviewed; no new defect. F1 (prompt tells servers to read MAPLE_INGEST_KEY while the shipped skill says inline the key) is still open.

  • guided-setup.browser.test.tsx renders ConnectInstructions with showCredentials off, so no ingestKeys query provider is needed
  • New test asserts the Node snippet carries process.env.MAPLE_INGEST_KEY and never the key

Still open from earlier reviews

What was checked
  • Credentials column now shows the private key, but CopyableField renders it into an <input>, masked by rrweb maskAllInputs (copyable-field.tsx:43, replay-privacy.ts:3)
  • No {{API_KEY}} placeholder survives in sdk-snippets.ts; guided-setup.tsx:195 interpolates only {{INGEST_URL}}
  • Replay-block assertion still bites: the Claude Code prompt CodeBlock keeps REPLAY_BLOCK_CLASS (guided-setup.tsx:217)

1f8b681 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@JeremyFunk JeremyFunk closed this Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant