---
id: w1/m16/t002
title: Env groups — REST (`/v1/env-groups`) + GraphQL + MCP surfaces + dashboard Env-Groups view
worker: worker1
status: done
estimate: 45m
depends_on: [w1/m16/t001]
---

## Objective

Expose the environment-group Core verbs (t001) over all three adapters and the dashboard. REST matches Render's public `/v1/env-groups` CRUD plus the link/unlink sub-routes; GraphQL follows Render's dashboard operations; MCP adds group tools. In the dashboard, add an Env-Groups management view (create/edit a group's vars, see linked services) and a "Linked Environment Groups" control on each service's Environment tab.

## Context

- One-core-three-adapters shape: each feature ships thin `rest.go`/`graphql.go`/`mcp.go` fragments beside its `service.go`, composed by `internal/api/server.go` (docs/ADR006-bex-api.md "One core, three adapters"). Add group adapters the same way.
- Render REST shapes to track: `/v1/env-groups` (CRUD) + `…/env-groups/{groupId}/services/{serviceId}` link/unlink (verify against Render's `render-public-api-1.json`, the same source the env-vars endpoints were verified against).
- GraphQL follows Render's dashboard (keys-first, nested where Render nests) — same principle the env-vars GraphQL used (`serviceEnvVarKeys`); the linked-groups list belongs on the `Service` type.
- Dashboard is the GraphQL client (TanStack Start + Apollo + shadcn) — see `dashboard/CLAUDE.md`; the service Environment tab is where env vars already live, so the "Linked Environment Groups" control goes there.
- CORS/auth already handle the dashboard origin — no new auth wiring.

## Steps

1. Add `rest.go` fragment: `/v1/env-groups` CRUD + `POST`/`DELETE` link/unlink sub-routes, matching Render's shapes; register in `internal/api/server.go`.
2. Add `graphql.go`: env-group queries/mutations + a linked-groups field on `Service`, following Render's dashboard operation names.
3. Add `mcp.go` tools: list/get/create/update/delete env groups + link/unlink, delegating to the same Core verbs.
4. Dashboard: an Env-Groups management view (list groups, create, edit a group's vars, show linked services) + a "Linked Environment Groups" control on the service Environment tab (link/unlink a group).

## Files

- `lego/backend/internal/secrets/rest.go`, `graphql.go`, `mcp.go` — group adapter fragments.
- `lego/backend/internal/api/server.go` — route/tool/resolver registration.
- `dashboard/` — Env-Groups view + Environment-tab linked-groups control + GraphQL operations (per `dashboard/CLAUDE.md`).

## Acceptance criteria

- [ ] REST `/v1/env-groups` CRUD + link/unlink round-trip a group and its service links, matching Render's shapes.
- [ ] GraphQL exposes env-group queries/mutations and a linked-groups field on `Service`.
- [ ] MCP tools cover create/list/get/update/delete + link/unlink, delegating to the same Core verbs.
- [ ] Dashboard: a group can be created, its vars edited, and linked/unlinked to a service from the Environment tab; linked services show the group.

## Out of scope

- Secret files on groups or per-service (t003).
- Render-vs-render.com parity audit (t004) and dedicated test coverage (t006).
