Skip to content

feat(cli,sdk,manifests): credential name resolution + platform ingress NetworkPolicy#1566

Open
markturansky wants to merge 5 commits into
mainfrom
fix/platform-ingress-netpol-base
Open

feat(cli,sdk,manifests): credential name resolution + platform ingress NetworkPolicy#1566
markturansky wants to merge 5 commits into
mainfrom
fix/platform-ingress-netpol-base

Conversation

@markturansky
Copy link
Copy Markdown
Contributor

@markturansky markturansky commented May 12, 2026

Summary

  • Credential name resolution: All acpctl credential subcommands (get, update, delete, token) now accept credential names in addition to IDs, with automatic name→ID resolution via FindByName
  • SDK FindByName: Added FindByName() to CredentialAPI in the Go SDK using TSL search (name = '<name>')
  • Apply uses FindByName: acpctl apply credential upsert now uses FindByName instead of Get (which only accepts IDs)
  • Delete name resolution: Top-level acpctl delete credential <name> resolves name→ID before deletion
  • Describe/Get fallback: Top-level acpctl describe credential and acpctl get credential fall back to FindByName when Get by ID fails
  • Platform ingress NetworkPolicy: Adds ingress rule allowing traffic from pods with ambient-code.io/managed: "true" label across namespaces
  • project_id compatibility: SDK Create retains project_id injection for backward compat with deployed server (TODO to remove after migration 202505120001 is deployed)

Tested against live cluster

< /dev/null | Operation | Command | Result |
|---|---|---|
| List | acpctl credential list | ✅ |
| Create | acpctl credential create --name ... --provider ... | ✅ |
| Get by name | acpctl credential get <name> | ✅ |
| Get by ID | acpctl credential get <id> | ✅ |
| Describe by name | acpctl describe credential <name> | ✅ |
| Update by name | acpctl credential update <name> --description ... | ✅ |
| Token by name | acpctl credential token <name> | ✅ |
| Delete by name | acpctl credential delete <name> --confirm | ✅ |
| Bind | acpctl credential bind <name> --project <project> | ✅ |
| Apply YAML | acpctl apply -f - (Credential) | ✅ |

Test plan

  • All credential CRUD operations tested against ROSA cluster via port-forward
  • Name resolution works for all subcommands (get, update, delete, token)
  • ID-based lookups still work (backward compatible)
  • credential bind creates RoleBinding with scope=credential
  • go build succeeds with no errors
  • Verify NetworkPolicy allows platform-managed pod traffic in staging

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Updated network policy to explicitly allow ingress from platform-designated namespaces, same-namespace pods, and pods with specific labels; removed broad allow-all ingress.
    • Added .secrets/ to .gitignore.
  • New Features

    • CLI: credential commands now accept and resolve credentials by name or ID for get/update/delete/token flows.
    • SDK: added credential lookup by name and included project-scoped payload handling for credential creation.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 12, 2026

Deploy Preview for cheerful-kitten-f556a0 canceled.

Name Link
🔨 Latest commit a5ef660
🔍 Latest deploy log https://app.netlify.com/projects/cheerful-kitten-f556a0/deploys/6a0b5633a4daae0008995af6

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

NetworkPolicy renamed to allow-platform-ingress and its ingress rules were replaced with explicit spec.ingress.from selectors (namespace label, same-namespace pods, pods labeled app: ambient-code-runner, and pods labeled ambient-code.io/managed: "true"). CLI and SDK updates add credential name→ID resolution and inject project_id on credential create; .secrets/ added to .gitignore.

Changes

Credential CLI & SDK

Layer / File(s) Summary
SDK: FindByName and Create payload
components/ambient-sdk/go-sdk/client/credential_extensions.go, components/ambient-sdk/go-sdk/client/credential_api.go
Adds CredentialAPI.FindByName and changes CredentialAPI.Create to marshal a payload embedding the credential plus an injected project_id.
CLI: resolver helper and import
components/ambient-cli/cmd/acpctl/credential/cmd.go, components/ambient-cli/cmd/acpctl/apply/cmd.go
Adds sdkclient import and resolveCredentialID helper that attempts Get(id) then FindByName(name); applyCredential now uses name-based lookup when deciding create vs update.
CLI: credential subcommand handlers
components/ambient-cli/cmd/acpctl/credential/cmd.go, components/ambient-cli/cmd/acpctl/delete/cmd.go, components/ambient-cli/cmd/acpctl/describe/cmd.go, components/ambient-cli/cmd/acpctl/get/cmd.go, components/ambient-cli/cmd/acpctl/apply/cmd.go
Updates get, update, delete, token, describe, and apply/delete flows to resolve provided identifier to a credential ID (using FindByName fallback) before calling SDK operations.

Manifests & misc

Layer / File(s) Summary
NetworkPolicy rename and ingress sources
components/manifests/base/runner-networkpolicy.yaml
metadata.name changed to allow-platform-ingress. Replaced an empty/allow-all ingress rule with explicit spec.ingress.from entries: namespaces labeled policy-group.network.openshift.io/ingress: "", same-namespace pods (podSelector: {}), pods with app: ambient-code-runner, and pods with ambient-code.io/managed: "true" across namespaces.
Ignore secrets directory
.gitignore
Added .secrets/ to ignore rules.

Possibly related PRs

  • ambient-code/platform#1553: Prior change to the same NetworkPolicy manifest that added an allow-from-runner-namespaces style policy; this PR renames and rewrites that policy's ingress sources.
  • ambient-code/platform#1182: Related credential command and lookup changes that touch acpctl credential flows.
  • ambient-code/platform#1378: Related NetworkPolicy changes tightening runner ingress controls.

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Security And Secret Handling ❌ Error SQL injection in FindByName via unescaped name interpolation. Error handling masks non-404 failures as "not found" across multiple commands. Escape name/provider in search filters; gate fallback to explicit not-found errors; propagate other failures to callers.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title follows Conventional Commits format (feat scope: description) and accurately summarizes the main changes: credential name resolution in CLI/SDK and NetworkPolicy replacement.
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.
Performance And Algorithmic Complexity ✅ Passed No performance regressions found. FindByName uses server-side search with Size(100); N+1 apply pattern is acceptable. No O(n²) algorithms, unbounded growth, or expensive loop operations.
Kubernetes Resource Safety ✅ Passed PR modifies only a NetworkPolicy resource with explicit ingress selectors and proper namespace scoping. No child resources, container specs, or RBAC changes. All safety check items either N/A or pass.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/platform-ingress-netpol-base
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/platform-ingress-netpol-base

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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

@markturansky markturansky force-pushed the fix/platform-ingress-netpol-base branch 2 times, most recently from 514e8d6 to baa4ad7 Compare May 12, 2026 18:23
…ress rules

The allow-from-runner-namespaces NP (#1553) uses podSelector: {} (all pods)
but only permits ingress from runner pods, blocking OpenShift router traffic
to the frontend and all other services. This caused outages on both Stage
and UAT clusters.

Replace with allow-platform-ingress that permits:
- OpenShift router ingress (policy-group.network.openshift.io/ingress label)
- Intra-namespace pod-to-pod traffic
- Runner pod ingress from any namespace (original intent of #1553)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@markturansky markturansky force-pushed the fix/platform-ingress-netpol-base branch from beb2298 to f416ffa Compare May 14, 2026 00:18
@markturansky markturansky changed the title fix(manifests): replace broken NetworkPolicy with proper platform ingress rules feat(cli,sdk,manifests): credential name resolution + platform ingress NetworkPolicy May 18, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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.

Inline comments:
In `@components/ambient-cli/cmd/acpctl/apply/cmd.go`:
- Around line 246-248: The code treats any error from
client.Credentials().FindByName(ctx, doc.Name) as a "not found" and falls
through to create; change this so only a genuine not-found error triggers
creation and all other errors are returned/handled. Specifically, in the block
around existing, err := client.Credentials().FindByName(ctx, doc.Name) (and the
subsequent token := os.ExpandEnv(doc.Token) / create path), detect the
provider/API "not found" sentinel (or inspect the returned error for a
NotFound/IsNotFound condition) and only execute the create logic when that
condition is true; for any other err, propagate or log and return the error
instead of proceeding to create. Ensure you reference
client.Credentials().FindByName, doc.Name and the create branch when making the
conditional change.

In `@components/ambient-cli/cmd/acpctl/credential/cmd.go`:
- Around line 471-479: The resolveCredentialID function currently falls back to
client.Credentials().FindByName on any error from client.Credentials().Get,
which can hide transport/auth/server errors; change it so that after calling
client.Credentials().Get(ctx, nameOrID) you only call FindByName when the Get
error indicates a not-found/404 condition (use the SDK's NotFound sentinel or
inspect the HTTP/status code), and for any other error return that error wrapped
with context (e.g., "failed to get credential %q") instead of falling back; keep
the final FindByName call and its existing not-found error message unchanged.

In `@components/ambient-cli/cmd/acpctl/delete/cmd.go`:
- Around line 136-139: The code currently ignores all errors from
client.Credentials().FindByName and proceeds to call Delete using deleteID;
change this so that if FindByName returns an error you only continue when the
error explicitly means "not found" and otherwise return/propagate the error.
Concretely, after calling client.Credentials().FindByName(ctx, name) check if
findErr != nil and then if !errors.Is(findErr, <package>.ErrNotFound) (or use
the repository/client IsNotFound helper if available) return or wrap findErr;
only when the error is the NotFound sentinel keep using deleteID (or set
deleteID from cred when found) before calling client.Credentials().Delete(ctx,
deleteID). Ensure you import errors and use the package-specific
ErrNotFound/IsNotFound symbol to distinguish not-found from other failures.

In `@components/ambient-cli/cmd/acpctl/get/cmd.go`:
- Around line 473-478: The current logic calls client.Credentials().FindByName
whenever client.Credentials().Get returns any error; change this so only a
not-found error triggers the fallback. In the block around
client.Credentials().Get(ctx, name) and client.Credentials().FindByName(ctx,
name), detect a not-found condition (e.g., errors.Is(err, <notFoundSentinel>) or
checking gRPC status.Code(err) == codes.NotFound) and only then call FindByName;
for any other error return fmt.Errorf("get credential %q: %w", name, err)
immediately. Keep the existing error wrap/message and the cred variable usage
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c05fe9fb-2da2-4577-80ec-1f5038d28dfa

📥 Commits

Reviewing files that changed from the base of the PR and between f416ffa and 9110752.

📒 Files selected for processing (9)
  • .gitignore
  • components/ambient-cli/cmd/acpctl/apply/cmd.go
  • components/ambient-cli/cmd/acpctl/credential/cmd.go
  • components/ambient-cli/cmd/acpctl/delete/cmd.go
  • components/ambient-cli/cmd/acpctl/describe/cmd.go
  • components/ambient-cli/cmd/acpctl/get/cmd.go
  • components/ambient-sdk/go-sdk/client/credential_api.go
  • components/ambient-sdk/go-sdk/client/credential_extensions.go
  • components/manifests/base/runner-networkpolicy.yaml
✅ Files skipped from review due to trivial changes (1)
  • .gitignore

Comment on lines +246 to 248
existing, err := client.Credentials().FindByName(ctx, doc.Name)
if err != nil {
token := os.ExpandEnv(doc.Token)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don’t treat every lookup error as create-miss.

Line 247 routes to create on any FindByName error. This should only happen on not-found; otherwise transient/API failures are misclassified and can produce incorrect create behavior.

As per coding guidelines, “Handle errors and edge cases explicitly rather than ignoring them.”

🤖 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 `@components/ambient-cli/cmd/acpctl/apply/cmd.go` around lines 246 - 248, The
code treats any error from client.Credentials().FindByName(ctx, doc.Name) as a
"not found" and falls through to create; change this so only a genuine not-found
error triggers creation and all other errors are returned/handled. Specifically,
in the block around existing, err := client.Credentials().FindByName(ctx,
doc.Name) (and the subsequent token := os.ExpandEnv(doc.Token) / create path),
detect the provider/API "not found" sentinel (or inspect the returned error for
a NotFound/IsNotFound condition) and only execute the create logic when that
condition is true; for any other err, propagate or log and return the error
instead of proceeding to create. Ensure you reference
client.Credentials().FindByName, doc.Name and the create branch when making the
conditional change.

Comment on lines +471 to +479
func resolveCredentialID(ctx context.Context, client *sdkclient.Client, nameOrID string) (string, error) {
cred, err := client.Credentials().Get(ctx, nameOrID)
if err == nil {
return cred.ID, nil
}
cred, err = client.Credentials().FindByName(ctx, nameOrID)
if err != nil {
return "", fmt.Errorf("credential %q not found by ID or name", nameOrID)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Only fallback to name lookup on NotFound errors.

Line 472 currently falls back to FindByName for any Get failure, which can mask transport/auth/server errors as “not found.” Gate fallback strictly to 404/not-found and propagate other errors with context.

As per coding guidelines, “Handle errors and edge cases explicitly rather than ignoring them.”

🤖 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 `@components/ambient-cli/cmd/acpctl/credential/cmd.go` around lines 471 - 479,
The resolveCredentialID function currently falls back to
client.Credentials().FindByName on any error from client.Credentials().Get,
which can hide transport/auth/server errors; change it so that after calling
client.Credentials().Get(ctx, nameOrID) you only call FindByName when the Get
error indicates a not-found/404 condition (use the SDK's NotFound sentinel or
inspect the HTTP/status code), and for any other error return that error wrapped
with context (e.g., "failed to get credential %q") instead of falling back; keep
the final FindByName call and its existing not-found error message unchanged.

Comment on lines +136 to +139
if cred, findErr := client.Credentials().FindByName(ctx, name); findErr == nil {
deleteID = cred.ID
}
if err := client.Credentials().Delete(ctx, deleteID); err != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silent fallback when name resolution fails.

Line 136 ignores FindByName errors and proceeds with Delete anyway. Restrict fallback to explicit not-found and return other errors; otherwise API/auth failures are hidden.

As per coding guidelines, “Handle errors and edge cases explicitly rather than ignoring them.”

🤖 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 `@components/ambient-cli/cmd/acpctl/delete/cmd.go` around lines 136 - 139, The
code currently ignores all errors from client.Credentials().FindByName and
proceeds to call Delete using deleteID; change this so that if FindByName
returns an error you only continue when the error explicitly means "not found"
and otherwise return/propagate the error. Concretely, after calling
client.Credentials().FindByName(ctx, name) check if findErr != nil and then if
!errors.Is(findErr, <package>.ErrNotFound) (or use the repository/client
IsNotFound helper if available) return or wrap findErr; only when the error is
the NotFound sentinel keep using deleteID (or set deleteID from cred when found)
before calling client.Credentials().Delete(ctx, deleteID). Ensure you import
errors and use the package-specific ErrNotFound/IsNotFound symbol to distinguish
not-found from other failures.

Comment on lines 473 to +478
cred, err := client.Credentials().Get(ctx, name)
if err != nil {
return fmt.Errorf("get credential %q: %w", name, err)
cred, err = client.Credentials().FindByName(ctx, name)
if err != nil {
return fmt.Errorf("get credential %q: %w", name, err)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use not-found-aware fallback in get credentials.

Line 474 should not automatically switch to FindByName for every Get error. Keep fallback for not-found only, and return non-404 failures directly.

As per coding guidelines, “Handle errors and edge cases explicitly rather than ignoring them.”

🤖 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 `@components/ambient-cli/cmd/acpctl/get/cmd.go` around lines 473 - 478, The
current logic calls client.Credentials().FindByName whenever
client.Credentials().Get returns any error; change this so only a not-found
error triggers the fallback. In the block around client.Credentials().Get(ctx,
name) and client.Credentials().FindByName(ctx, name), detect a not-found
condition (e.g., errors.Is(err, <notFoundSentinel>) or checking gRPC
status.Code(err) == codes.NotFound) and only then call FindByName; for any other
error return fmt.Errorf("get credential %q: %w", name, err) immediately. Keep
the existing error wrap/message and the cred variable usage unchanged.

…commands

Add resolveCredentialID helper to credential subcommand (get, update, delete,
token) enabling name-based lookups with ID fallback. Add FindByName to SDK
credential_extensions.go using TSL search. Fix apply to use FindByName for
upsert. Add platform-managed pod ingress rule to runner NetworkPolicy.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@markturansky markturansky force-pushed the fix/platform-ingress-netpol-base branch from 9110752 to a5ef660 Compare May 18, 2026 18:10
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