Skip to content

Reuse org-registered external connections without re-entering secrets - #625

Merged
xlight05 merged 8 commits into
mainfrom
marketplace/08-consume
Aug 26, 2026
Merged

Reuse org-registered external connections without re-entering secrets#625
xlight05 merged 8 commits into
mainfrom
marketplace/08-consume

Conversation

@kaje94

@kaje94 kaje94 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Why this exists

Orgs can already register an external connection once (for example Stripe), with keys, docs, and environment values stored at the org. Until this PR, a project that needed that same connection still treated it like a brand-new project-local secret: the design agent would not prefer the org record, Deployments still offered Configure, and Build still opened a drawer asking for the same secrets.

This PR makes consume mean reuse. If a component depends on a name that is already registered for the org, the project uses that record. Nobody re-enters keys or secrets — not in Connections, and not in the Build drawer. OpenChoreo still gets a Resource instance in the project so the workload can bind to the type; the values stay on the org record and are templated per environment.

Two kinds of external resource (needed to read the rest)

Kind Who owns the values What the user does in this project
Registered External The org catalog (one set of env values for the whole org) Depend on the registered name. No Connection values dialog. No Build-drawer secret fields.
Project External This project Same as today: Configure / Build drawer collects values into the project's secret store.

A name is one kind or the other. You cannot convert stripe from Registered to Project External, and you cannot override the org's values under that name. If this project needs its own Stripe, it creates a new name (for example acme-stripe) as a Project External.

What you will see

Design agent. When a component needs an external dependency that already exists in the org catalog, the agent prefers that Registered name. The user can still chat to pick a different Registered record, or create a Project External under a new name.

Deployments → Connections. A Registered name has no Configure button (the org already holds the values). A new-name Project External still has Configure and still saves into the project secret store. That save path never calls the org register API.

Build. GET /projects/{project}/build/preflight does not emit external-config for a Registered name, so the dependency drawer does not ask for those secrets. A Project External on the same build still collects as today. POST /build still authors a Resource instance from org cells (typed drawer values were already ignored).

API. POST /projects/{projectName}/dependencies/external-resources/{name}/values returns 409 Conflict when {name} is Registered (“values live on the org record”). The same POST for a Project External still provisions as before.

Agents (MCP). list_external_resources lists Registered records even before any project uses them, including consumption instructions and pointers to org resource docs — not only name + {key, secret} after provision.

What this PR does not change

  • It does not retire Settings (that is a later change).
  • It does not let a project override org secrets for a Registered name.
  • Registering a name that already exists (either kind) is still rejected; that rule shipped earlier on this stack.

How to verify

  • Depend on a Registered name → Connections has no Configure; collect-values POST is 409; the project still authors a Resource instance that points at org values.
  • Click Build on a project that only depends on a Registered name → no secret fields for that name (preflight has no external-config item).
  • Mix Registered + Project External (e.g. weather + FX) → Build drawer collects only the Project External.
  • Depend on a new name that is only a Project External → Configure still opens; collect-values still provisions project secrets and does not create org catalog cells.
  • MCP list includes a Registered record with zero consumers, plus consumption instructions and resource-docs pointers.
  • While the org catalog is still loading or has failed, Configure stays hidden (we do not guess that a name is project-local).

Seams already covered in tests:

  • go test in aep-api: internal/delivery/build (Registered preflight skip), internal/dependencies/provisioning, internal/dependencies/mcpdiscovery, internal/organization
  • console: DeploymentsPage.test.tsx
  • skills: workflow_skill.test.ts

Stack

Layer on the Resources stack. Base is marketplace/05-chat (#624), not main. Merge with gh stack merge 625 --yes, not gh pr merge.

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 56 minutes.

View limit details

Limit details: You’ve used the included review currently available.

This review ran on the open-source allowance, not this organization's plan, because the pull request author doesn't have an assigned seat. Waiting won't change this — ask an organization admin to assign them a seat, or add seats in Billing if every seat is already assigned, then retry.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 33368458-dc8b-46e8-a045-b973ecae73e8

📥 Commits

Reviewing files that changed from the base of the PR and between 9ab96a1 and 6f3a7ee.

⛔ Files ignored due to path filters (1)
  • services/aep-api/internal/gen/server_gen.go is excluded by !**/gen/**
📒 Files selected for processing (27)
  • apps/console/src/features/projects/components/DeploymentsPage.test.tsx
  • apps/console/src/features/projects/components/DeploymentsPage.tsx
  • packages/contracts/api/v1/openapi.yaml
  • runners/remote-worker/src/lib/workflow_skill.test.ts
  • services/aep-api/internal/app/app.go
  • services/aep-api/internal/app/build_adapters.go
  • services/aep-api/internal/clients/openchoreo/external_resource_type.go
  • services/aep-api/internal/delivery/build/preflight.go
  • services/aep-api/internal/delivery/build/preflight_test.go
  • services/aep-api/internal/dependencies/README.md
  • services/aep-api/internal/dependencies/external_catalog.go
  • services/aep-api/internal/dependencies/mcpdiscovery/mcp_server_test.go
  • services/aep-api/internal/dependencies/mcpdiscovery/mcp_tools.go
  • services/aep-api/internal/dependencies/mcpdiscovery/ports.go
  • services/aep-api/internal/dependencies/provisioning/build_provision.go
  • services/aep-api/internal/dependencies/provisioning/build_provision_test.go
  • services/aep-api/internal/dependencies/provisioning/external_catalog.go
  • services/aep-api/internal/dependencies/provisioning/memory_value_plane.go
  • services/aep-api/internal/dependencies/provisioning/ports.go
  • services/aep-api/internal/dependencies/provisioning/provisioning_component_test.go
  • services/aep-api/internal/dependencies/provisioning/register.go
  • services/aep-api/internal/dependencies/provisioning/update.go
  • services/aep-api/internal/dependencies/provisioning/value_service.go
  • services/aep-api/internal/organization/secret_ref_writer.go
  • services/aep-api/internal/organization/secret_ref_writer_test.go
  • skills/aep/references/external-dependency-research.md
  • skills/architecture/SKILL.md

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

@kaje94 kaje94 changed the title marketplace/08 consume 08 — Consume Registered External without re-entry Aug 25, 2026
@kaje94
kaje94 force-pushed the marketplace/08-consume branch from 39badd9 to 96a579b Compare August 25, 2026 13:33
@kaje94 kaje94 changed the title 08 — Consume Registered External without re-entry Reuse org-registered external connections without re-entering secrets Aug 25, 2026
@kaje94
kaje94 marked this pull request as ready for review August 25, 2026 13:43
@kaje94
kaje94 force-pushed the marketplace/08-consume branch 2 times, most recently from ba33b5c to 9ae20ec Compare August 25, 2026 14:08
@kaje94
kaje94 force-pushed the marketplace/08-consume branch from 8958718 to f0c3d02 Compare August 26, 2026 15:55
@xlight05
xlight05 force-pushed the marketplace/08-consume branch from f0c3d02 to df99581 Compare August 26, 2026 16:45
@xlight05
xlight05 force-pushed the marketplace/08-consume branch from df99581 to 4283d88 Compare August 26, 2026 16:46
@xlight05
xlight05 force-pushed the marketplace/08-consume branch from 4283d88 to 9c51f5a Compare August 26, 2026 16:46
@xlight05
xlight05 force-pushed the marketplace/08-consume branch from 9c51f5a to a3739e3 Compare August 26, 2026 16:47
Base automatically changed from marketplace/05-chat to main August 26, 2026 16:48
kaje94 added 8 commits August 26, 2026 22:18
Values live on the org record; the consuming project still authors a Resource instance at build.
Design-time list_external_resources includes unconsumed Registered records and org resource docs pointers.
Register now stores the OrgSecretWriter vault key on the value plane so consume authoring can set binding secretStorePath; Connections wait for the org catalog before offering Configure.
An error settle left registeredNames empty, so a Registered External
could open the project values dialog. Fail closed and surface retry.
Preflight emitted external-config while project provision was still
unknown, so Continue forced typing org secrets that POST /build ignores.
@xlight05
xlight05 force-pushed the marketplace/08-consume branch from a3739e3 to 6f3a7ee Compare August 26, 2026 16:48
@xlight05
xlight05 merged commit 86c1155 into main Aug 26, 2026
1 check passed
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.

2 participants