Skip to content

fix: infer vlt org from coordinate owner - #5

Merged
ygpark80 merged 1 commit into
mainfrom
fix/13-vlt-org-inference
Aug 10, 2026
Merged

fix: infer vlt org from coordinate owner#5
ygpark80 merged 1 commit into
mainfrom
fix/13-vlt-org-inference

Conversation

@ygpark80

@ygpark80 ygpark80 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

User description

Refs circlesac/vault-service#13

Changes

  • Infer an accessible organization from each vlt://github.com/<owner>/... reference.
  • Preserve personal fallback only for missing organizations or non-membership, while surfacing other authorization failures.
  • Reject explicit org/reference-owner mismatches and cache concurrent owner probes for read, run, and inject.
  • Document the vlt:// exception to the general personal-by-default account rule.

Testing

  • bun test node/src/ cli/src/ — 73 pass, 1 platform-specific skip
  • npm run build:sdk
  • bun run build
  • Production cvlt read without --org returns the same value as explicit --org circlesac
  • Production cvlt run --env-file and cvlt inject resolve owner-global references without --org
  • Explicit mismatched --org melten is rejected before reading

CodeAnt-AI Description

Infer the organization for vlt:// references from their owner

What Changed

  • vlt://github.com/<owner>/... reads now use the owner’s organization when the current credential can access it, without requiring --org
  • References for inaccessible or personal owners continue using the personal account
  • Explicit organization selections must match the vlt:// owner and now fail clearly when they do not
  • Mixed-owner references in run and inject resolve each owner independently, while repeated checks reuse the same access result
  • Documentation now explains the vlt:// organization inference exception

Impact

✅ Organization secrets resolve without manually selecting --org
✅ Personal fallback for inaccessible or personal owners
✅ Clear errors for mismatched organization selections

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • vlt:// secret references can now infer an accessible owner organization automatically.
    • Personal accounts remain the default scope for other commands.
    • Mixed-owner references resolve each owner independently for run and inject.
    • Explicit organization scopes are validated, with clear rejection for mismatches.
    • GitHub OIDC continues using its fixed organization scope.
  • Documentation

    • Updated CLI and README guidance to explain owner inference, scope defaults, and fallback behavior.

@codeant-ai

codeant-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR cc48ddf Aug 10, 2026 · 07:18 07:21

@codeant-ai

codeant-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The client now infers accessible organization owners for vlt:// reads. It validates explicit organization scopes, caches access probes, supports owner-specific secret requests, updates CLI wiring, and documents the scope rules.

Changes

Owner-aware secret resolution

Layer / File(s) Summary
Owner configuration resolution
node/src/api.ts, node/src/api.test.ts
The API resolves normalized owners, probes organization access through /v1/status, caches probes, validates explicit organizations, and falls back to personal configuration when membership is unavailable. Tests cover these paths.
Owner-scoped secret request path
node/src/api.ts, node/src/cli.ts, cli/src/index.ts, README.md
secretsApiForOwner uses resolved owner configuration for secret reads. The CLI passes the cvlt:// reference owner and documents personal defaults and inferred organization scope. The README documents the updated vlt:// rules.

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

Sequence Diagram(s)

sequenceDiagram
  participant readSecret
  participant secretsApiForOwner
  participant getConfigForVltOwner
  participant rawSecretsApiWithConfig
  readSecret->>secretsApiForOwner: pass reference owner and secret path
  secretsApiForOwner->>getConfigForVltOwner: resolve owner configuration
  getConfigForOwner-->>secretsApiForOwner: return VaultConfig
  secretsApiForOwner->>rawSecretsApiWithConfig: request secret with VaultConfig
  rawSecretsApiWithConfig-->>readSecret: return secret response
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: inferring the organization from the coordinate owner for vlt references.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/13-vlt-org-inference

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.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Aug 10, 2026
@ygpark80
ygpark80 merged commit 046cc42 into main Aug 10, 2026
2 checks passed
@ygpark80
ygpark80 deleted the fix/13-vlt-org-inference branch August 10, 2026 07:19

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
node/src/api.test.ts (1)

282-301: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover in-flight probe deduplication.

Lines 291-301 await the first resolution before starting the second resolution. This verifies completed-result caching only. Start both resolutions before awaiting either one. Assert that one status request occurs for the normalized owner.

Proposed test update
-    expect(await getConfigForVltOwner("CirclesAC")).toEqual({
+    const [first, second] = await Promise.all([
+      getConfigForVltOwner("CirclesAC"),
+      getConfigForVltOwner("circlesac"),
+    ])
+    expect(first).toEqual({
       baseUrl: "https://vault.circles.ac/circlesac",
       token,
       org: "circlesac",
     })
-    expect(await getConfigForVltOwner("circlesac")).toEqual({
+    expect(second).toEqual({
       baseUrl: "https://vault.circles.ac/circlesac",
       token,
       org: "circlesac",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@node/src/api.test.ts` around lines 282 - 301, Update the test around
getConfigForVltOwner to start both owner lookups concurrently before awaiting
either result, then assert both return the expected normalized configuration and
fetchSpy records exactly one status request. This must verify in-flight probe
deduplication rather than only completed-result caching.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@node/src/api.test.ts`:
- Around line 282-301: Update the test around getConfigForVltOwner to start both
owner lookups concurrently before awaiting either result, then assert both
return the expected normalized configuration and fetchSpy records exactly one
status request. This must verify in-flight probe deduplication rather than only
completed-result caching.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a619fdfd-bc45-4774-8759-8a103682cd05

📥 Commits

Reviewing files that changed from the base of the PR and between da8524c and cc48ddf.

📒 Files selected for processing (5)
  • README.md
  • cli/src/index.ts
  • node/src/api.test.ts
  • node/src/api.ts
  • node/src/cli.ts

Comment thread node/src/api.ts
Comment on lines +161 to +164
async function canAccessOrg(config: VaultConfig, org: string): Promise<boolean> {
const key = `${config.baseUrl}\n${org}`
let probe = orgAccessProbes.get(key)
if (!probe) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The probe cache key omits the bearer token and has no expiry. If credentials are refreshed, rotated, or permissions change while the process remains alive, a result obtained with the old token is reused: a stale false result forces an accessible organization to personal scope, while a stale true result continues selecting an organization after access is revoked. Include the credential identity/token validity in the cache key or invalidate probes whenever the resolved credential changes, and add an expiry policy. [cache]

Severity Level: Major ⚠️
- ⚠️ Long-lived SDK reads can use stale organization scope.
- ❌ Rotated credentials may fail owner-specific secret lookups.
- ⚠️ Revoked membership remains selected until process restart.

Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** node/src/api.ts
**Line:** 161:164
**Comment:**
	*Cache: The probe cache key omits the bearer token and has no expiry. If credentials are refreshed, rotated, or permissions change while the process remains alive, a result obtained with the old token is reused: a stale false result forces an accessible organization to personal scope, while a stale true result continues selecting an organization after access is revoked. Include the credential identity/token validity in the cache key or invalidate probes whenever the resolved credential changes, and add an expiry policy.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread node/src/api.ts
Comment on lines +231 to +237
export async function secretsApiForOwner<T = unknown>(
owner: string,
path: string,
opts: { method?: string; body?: unknown } = {}
): Promise<T> {
try {
return await rawSecretsApiWithConfig<T>(await getConfigForVltOwner(owner), path, opts)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The new owner-aware helper is used by the CLI, but the SDK's createVaultClient().read() path still calls rawSecretsApi, which resolves only getConfig() and therefore reads vlt:// references from the personal account. Consumers using the SDK receive different behavior from the CLI and can get a personal-account lookup or failure instead of the owner's organization secret. Update the SDK read path to parse the owner and use the owner-aware request path. [incomplete implementation]

Severity Level: Major ⚠️
- ❌ SDK `read()` ignores `vlt://` organization owners.
- ❌ Personal lookup can fail for organization secrets.
- ⚠️ CLI and SDK produce inconsistent reference behavior.

Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** node/src/api.ts
**Line:** 231:237
**Comment:**
	*Incomplete Implementation: The new owner-aware helper is used by the CLI, but the SDK's `createVaultClient().read()` path still calls `rawSecretsApi`, which resolves only `getConfig()` and therefore reads `vlt://` references from the personal account. Consumers using the SDK receive different behavior from the CLI and can get a personal-account lookup or failure instead of the owner's organization secret. Update the SDK read path to parse the owner and use the owner-aware request path.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant