feat(apps): declare envMappings per app; return in GET /api/connections#16
Merged
matoushavlena merged 1 commit intomainfrom Apr 21, 2026
Merged
feat(apps): declare envMappings per app; return in GET /api/connections#16matoushavlena merged 1 commit intomainfrom
matoushavlena merged 1 commit intomainfrom
Conversation
d276a5c to
f2382dc
Compare
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
When a user grants a connection (e.g. Google Drive) in the Configure Agent dialog, any envMappings OneCLI declared for that app get appended to the agent's editable env list. The user can then edit or remove the entries like any other custom env var. Requires a companion OneCLI patch (kagenti/onecli#16) that adds `envMappings` as a first-class field on the app registry and returns it on `GET /api/connections`. Why this over storing envs on the connection itself: envs belong with the agent (that's the K8s resource that consumes them), and users may reasonably want to tweak the env name or remove a mapping for a specific agent without losing the grant. Humr has zero provider knowledge — the env-injection contract lives in OneCLI next to the OAuth config for each app. - api-server-api: `AppConnectionView.envMappings?` for UI consumption - api-server: passes through OneCLI's joined envMappings verbatim on `connections.list` - ui: `EditAgentSecretsDialog.toggleApp` appends new app's envMappings to the agent env list on first grant (dedupe by env name — user-set wins); ungrant leaves envs alone so user edits aren't lost - ui: `ConnectorsView` displays env names on each connection row so users can see what a grant will contribute - docs: google-workspace README describes the new grant-time flow Signed-off-by: Matous Havlena <havlenma@gmail.com>
3 tasks
f2382dc to
d75591c
Compare
Some apps go through CLIs that expect a specific env var name holding the credential sentinel — `gws` for Google Workspace wants `GOOGLE_WORKSPACE_CLI_TOKEN`. Declares this as a first-class field on `AppDefinition`, co-located with the rest of the app's metadata (scopes, permissions, OAuth config). `GET /api/connections` now joins `envMappings` from the app registry into each connection row, same shape as the existing `providerName` join. Consumers (Humr) drop their provider→env table and just read the field from the response — no client-side writes, no backfill, no per-connection metadata. Added only to `gmail` and `google-drive` for now (both share the same `GOOGLE_WORKSPACE_CLI_TOKEN` via `googleWorkspaceEnvMappings`). Other providers opt in by setting the field — no other code changes needed. Signed-off-by: Matous Havlena <havlenma@gmail.com>
d75591c to
7eb0498
Compare
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
…ump onecli - Test fixture in connections-service.test.ts used literal Google provider names and env var strings. Humr's service is provider-agnostic (just passes OneCLI's joined fields to the view) — swap to a fictional `acme-app` / `ACME_TOKEN` fixture so the test asserts pass-through behavior without coupling to any specific provider. - On ungrant, toggleApp now removes envs the app contributed *only if* they're still untouched (name + value match the declared mapping) AND no other still-granted app declares the same envName. The double guard protects shared envs (Gmail + Drive both want GOOGLE_WORKSPACE_CLI_TOKEN — ungranting Drive while Gmail is still granted must not drop the env) and user edits (an edited value signals intent the toggle shouldn't undo). - Bump OneCLI image to 0.0.20 — ships the app-registry envMappings field this PR depends on (kagenti/onecli#16). Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
When a user grants a connection (e.g. Google Drive) in the Configure Agent dialog, any envMappings OneCLI declared for that app get appended to the agent's editable env list. The user can then edit or remove the entries like any other custom env var. On ungrant, entries that are still untouched (name + value match the declared mapping) and not required by any other still-granted app are removed automatically. Requires OneCLI 0.0.20+ which adds `envMappings` as a first-class field on the app registry and returns it on `GET /api/connections` (kagenti/onecli#16). Why this over storing envs on the connection itself: envs belong with the agent (that's the K8s resource that consumes them), and users may reasonably want to tweak the env name or remove a mapping for a specific agent without losing the grant. Humr has zero provider knowledge — the env-injection contract lives in OneCLI next to the OAuth config for each app. - api-server-api: `AppConnectionView.envMappings?` for UI consumption - api-server: passes through OneCLI's joined envMappings verbatim on `connections.list`; tests use a fictional provider fixture so they don't couple to any specific provider - ui: `EditAgentSecretsDialog.toggleApp` appends new app's envMappings to the agent env list on first grant (dedupe by env name — user-set wins); on ungrant removes entries only if they match the declared mapping and no other still-granted app declares the same envName - ui: `ConnectorsView` displays env names on each connection row so users can see what a grant will contribute - deploy: bump OneCLI image to 0.0.20 - docs: google-workspace README describes the new grant-time flow Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
When a user grants a connection (e.g. Google Drive) in the Configure Agent dialog, any envMappings OneCLI declared for that app get appended to the agent's editable env list. The user can then edit or remove the entries like any other custom env var. On ungrant, entries that are still untouched (name + value match the declared mapping) and not required by any other still-granted app are removed automatically. Requires OneCLI 0.0.20+ which adds `envMappings` as a first-class field on the app registry and returns it on `GET /api/connections` (kagenti/onecli#16). Why this over storing envs on the connection itself: envs belong with the agent (that's the K8s resource that consumes them), and users may reasonably want to tweak the env name or remove a mapping for a specific agent without losing the grant. Humr has zero provider knowledge — the env-injection contract lives in OneCLI next to the OAuth config for each app. - api-server-api: `AppConnectionView.envMappings?` for UI consumption - api-server: passes through OneCLI's joined envMappings verbatim on `connections.list`; tests use a fictional provider fixture so they don't couple to any specific provider - ui: `EditAgentSecretsDialog.toggleApp` appends new app's envMappings to the agent env list on first grant (dedupe by env name — user-set wins); on ungrant removes entries only if they match the declared mapping and no other still-granted app declares the same envName - ui: `ConnectorsView` displays env names on each connection row so users can see what a grant will contribute - deploy: bump OneCLI image to 0.0.20 - docs: google-workspace README describes the new grant-time flow Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
When a user grants a connection (e.g. Google Drive) in the Configure Agent dialog, any envMappings OneCLI declared for that app get appended to the agent's editable env list. The user can then edit or remove the entries like any other custom env var. On ungrant, entries that are still untouched (name + value match the declared mapping) and not required by any other still-granted app are removed automatically. Requires OneCLI 0.0.20+ which adds `envMappings` as a first-class field on the app registry and returns it on `GET /api/connections` (kagenti/onecli#16). Why this over storing envs on the connection itself: envs belong with the agent (that's the K8s resource that consumes them), and users may reasonably want to tweak the env name or remove a mapping for a specific agent without losing the grant. Humr has zero provider knowledge — the env-injection contract lives in OneCLI next to the OAuth config for each app. - api-server-api: `AppConnectionView.envMappings?` for UI consumption - api-server: passes through OneCLI's joined envMappings verbatim on `connections.list`; tests use a fictional provider fixture so they don't couple to any specific provider - ui: `EditAgentSecretsDialog.toggleApp` appends new app's envMappings to the agent env list on first grant (dedupe by env name — user-set wins); on ungrant removes entries only if they match the declared mapping and no other still-granted app declares the same envName - ui: `ConnectorsView` displays env names on each connection row so users can see what a grant will contribute - deploy: bump OneCLI image to 0.0.20 - docs: google-workspace README describes the new grant-time flow Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
When a user grants a connection (e.g. Google Drive) in the Configure Agent dialog, any envMappings OneCLI declared for that app get appended to the agent's editable env list. The user can then edit or remove the entries like any other custom env var. On ungrant, entries that are still untouched (name + value match the declared mapping) and not required by any other still-granted app are removed automatically. Requires OneCLI 0.0.20+ which adds `envMappings` as a first-class field on the app registry and returns it on `GET /api/connections` (kagenti/onecli#16). Why this over storing envs on the connection itself: envs belong with the agent (that's the K8s resource that consumes them), and users may reasonably want to tweak the env name or remove a mapping for a specific agent without losing the grant. Humr has zero provider knowledge — the env-injection contract lives in OneCLI next to the OAuth config for each app. - api-server-api: `AppConnectionView.envMappings?` for UI consumption - api-server: passes through OneCLI's joined envMappings verbatim on `connections.list`; tests use a fictional provider fixture so they don't couple to any specific provider - ui: `EditAgentSecretsDialog.toggleApp` appends new app's envMappings to the agent env list on first grant (dedupe by env name — user-set wins); on ungrant removes entries only if they match the declared mapping and no other still-granted app declares the same envName - ui: `ConnectorsView` displays env names on each connection row so users can see what a grant will contribute - deploy: bump OneCLI image to 0.0.20 - docs: google-workspace README describes the new grant-time flow Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
Extends ADR-024's "env declared by credential owner" principle to OAuth app connections. Three rationale points: users shouldn't have to know env var names; Humr shouldn't decide env names for OneCLI-owned providers; agent templates shouldn't bake connection envs since connections are a runtime choice. Shipped in kagenti/onecli#16 + #262. Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
Extends ADR-024's "env declared by credential owner" principle to OAuth app connections. Three rationale points: users shouldn't have to know env var names; Humr shouldn't decide env names for OneCLI-owned providers; agent templates shouldn't bake connection envs since connections are a runtime choice. Shipped in kagenti/onecli#16 + #262. Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
Extends ADR-024's "env declared by credential owner" principle to OAuth app connections. Three rationale points: users shouldn't have to know env var names; Humr shouldn't decide env names for OneCLI-owned providers; agent templates shouldn't bake connection envs since connections are a runtime choice. Shipped in kagenti/onecli#16 + #262. Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
Slimmed the ADR from 143 lines to 43 — kept the decision, dropped implementation detail (zod schemas, Prisma columns, key files, verification blocks) that belongs in commit messages and PRs. Unified the secret + connection paths under one principle: "the entity that owns the credential declares which env vars it needs." The two paths differ in storage (secret metadata vs OneCLI app registry) and flow (controller-merged vs UI-populated) but share the rationale. Captures the four guiding constraints: users shouldn't know env names; Humr shouldn't decide env names for OneCLI-owned providers; templates shouldn't bake connection envs; power users can still tweak per-agent. Tracked in kagenti/onecli#9 (secrets), kagenti/onecli#16 + #262 (connections). Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 21, 2026
Slimmed the ADR from 143 lines to 43 — kept the decision, dropped implementation detail (zod schemas, Prisma columns, key files, verification blocks) that belongs in commit messages and PRs. Unified the secret + connection paths under one principle: "the entity that owns the credential declares which env vars it needs." The two paths differ in storage (secret metadata vs OneCLI app registry) and flow (controller-merged vs UI-populated) but share the rationale. Captures the four guiding constraints: users shouldn't know env names; Humr shouldn't decide env names for OneCLI-owned providers; templates shouldn't bake connection envs; power users can still tweak per-agent. Tracked in kagenti/onecli#9 (secrets), kagenti/onecli#16 + #262 (connections). Signed-off-by: Matous Havlena <havlenma@gmail.com>
matoushavlena
added a commit
to kagenti/humr
that referenced
this pull request
Apr 22, 2026
Slimmed the ADR from 143 lines to 43 — kept the decision, dropped implementation detail (zod schemas, Prisma columns, key files, verification blocks) that belongs in commit messages and PRs. Unified the secret + connection paths under one principle: "the entity that owns the credential declares which env vars it needs." The two paths differ in storage (secret metadata vs OneCLI app registry) and flow (controller-merged vs UI-populated) but share the rationale. Captures the four guiding constraints: users shouldn't know env names; Humr shouldn't decide env names for OneCLI-owned providers; templates shouldn't bake connection envs; power users can still tweak per-agent. Tracked in kagenti/onecli#9 (secrets), kagenti/onecli#16 + #262 (connections). Signed-off-by: Matous Havlena <havlenma@gmail.com>
This was referenced Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OneCLI now declares pod-env-var injection next to the app definition it belongs with, and returns those mappings in
GET /api/connectionsso consumers don't need provider-specific knowledge.Consumer (Humr) reads
connection.envMappingsdirectly; no PATCH, no backfill, no per-connection metadata, no database migration.Why
Previously Humr kept a hardcoded provider→env table mirrored across its TS + Go code. Adding a new Google app (Calendar, Sheets) to OneCLI required a Humr PR to teach the controller which env var the new provider contributed. That knowledge belongs with the app definition — OneCLI already owns the OAuth scopes, permissions, and client config for each provider.
What changes
apps/web/src/lib/env-mapping.ts(new):envMappingSchema(zod) +EnvMappingtype viaz.infer. Single source of truth.lib/validations/secret.tsnow imports the schema instead of redefining it.apps/web/src/lib/apps/types.ts:AppDefinition.envMappings?: EnvMapping[].apps/web/src/lib/apps/google-oauth.ts:googleWorkspaceEnvMappingsconst.gws.apps/web/src/app/api/connections/route.ts: joinenvMappingsfrom the registry into each connection row, same shape as the existingproviderNamejoin (widened the lookup fromproviderNameByIdtoappById).Test plan
pnpm --filter @onecli/web exec tsc --noEmitpassespnpm --filter @onecli/web lintpassescargo fmt --check+cargo clippy -- -D warningspassGET /api/connectionswith a gmail/calendar/drive/sheets connection returnsenvMappings: [{envName: "GOOGLE_WORKSPACE_CLI_TOKEN", placeholder: "humr:sentinel"}]; with a github/resend/spotify/youtube connection returnsenvMappings: nullConsumer
Unblocks kagenti/humr#262, which reads the field directly and populates the agent env on grant (editable like any other env).