aws-samples / aws-samples/sample-autonomous-cloud-coding-agents

Add Slack-button approvals for Cedar HITL approval gates

Abierto
#112 2 comentarios 0 reacciones 0 asignados Ver en GitHub
adapters security
Lenguaje dominante
TypeScript
Estrellas
143
Forks
46
Merge medio
3 d 10 h
PR fusionados (30 d)
24

Descripción

> **Follow-up from [PR #88](https://github.com/aws-samples/sample-autonomous-cloud-coding-agents/pull/88)** — Cedar HITL approvals work via CLI today; Slack interactivity is wired but not yet used for approvals.

## Functional description

PR #88 ships a complete Cedar HITL approval flow: when an agent attempts a sensitive operation (force push, write to .env, etc.), the task pauses in `AWAITING_APPROVAL` status and an operator must run `bgagent approve ` (or `deny`) to resume or fail it. The CLI works well for individual operators, but **for team workflows (CI bots, on-call rotations, mobile approvals) the natural surface is Slack**, not a terminal.

ABCA already has a working `SlackIntegration` construct (`cdk/src/constructs/slack-integration.ts`) with `InteractionsFn` handling `block_actions` callbacks, plus `SlackNotifyFn` posting task lifecycle events. The plumbing for "user clicks a button in a Slack message → Lambda processes the action → state update" already works for `link_account_action` and a few others. **Extending it with `approve_action:` / `deny_action:` block_actions would close the HITL loop end-to-end without any new infrastructure.**

**User-visible impact (what's missing today):**

- Operator on phone gets a Slack message: "Task abc-123 is awaiting approval (force push)." They have to switch to a terminal, run `bgagent login`, run `bgagent approve abc-123 req-456`. Friction is high enough that approvals stall.
- CI bots can't approve via Slack workflow steps (they could call the API directly, but the Slack-button surface would be the cleanest integration).
- Any team using the dashboard for visibility but the CLI for action lives in two contexts.

**With this issue resolved:**

- Slack message gains "✅ Approve" / "❌ Deny" buttons.
- Click triggers `block_actions` callback, Lambda extracts the user identity (already mapped via `SlackUserMappingTable`), calls the same `approve-task` / `deny-task` handlers the CLI uses.
- Operator never leaves Slack.

## Technical context

**Existing plumbing:**

- `cdk/src/handlers/slack-interactions.ts` — handles incoming `block_actions` payloads. Already validates Slack signatures, extracts the action_id, maps the Slack user to an ABCA user via `SlackUserMappingTable`. Adding new action_ids is a switch-case.
- `cdk/src/handlers/shared/slack-blocks.ts` — Block Kit template helpers. Has `taskCreated`, `taskCompleted`, etc.; needs an `approvalRequest` template that includes the buttons.
- `cdk/src/handlers/slack-notify.ts` — currently called by FanOutConsumer when an `approval_requested` event is dispatched. Today it posts plain text; would need to switch to the Block Kit template.
- `cdk/src/handlers/approve-task.ts` / `deny-task.ts` — the existing handlers. Their interfaces (`POST /tasks/{id}/approve` etc.) are reusable; the Slack interactions Lambda would call into the same shared business logic via `cdk/src/handlers/shared/approval-action.ts` (need to extract the core from the HTTP handler into a shared module).

**Net new code:**

- `slackApprovalRequestBlocks(taskId, requestId, ruleIds)` in `slack-blocks.ts` (~50 LOC).
- `handleApproveAction` / `handleDenyAction` in `slack-interactions.ts` (~80 LOC each).
- Refactor approve-task.ts / deny-task.ts to extract a `processApprovalDecision(...)` shared function that both the HTTP handler and the Slack handler call (~30 LOC refactor + tests).
- Wiring: `slack-notify.ts` switches to the Block Kit template when `event.event_type === 'approval_requested'`.

**Estimated effort:** ~1 day for a single dev including tests + E2E validation against the dev stack.

## Proposed options

**Recommended path:**

1. Refactor the approve/deny handler core into `cdk/src/handlers/shared/approval-decision.ts` (no behavior change; passes existing tests).
2. Add Block Kit template + new action_id branches in `slack-interactions.ts`.
3. Update `slack-notify.ts` to use the Block Kit template for `approval_requested` events.
4. Add CDK + agent-side E2E test that simulates the Slack interaction flow end-to-end (the existing pattern from `cdk/test/handlers/slack-interactions.test.ts` extends naturally).

**Alternative considered:** building a separate Slack approval handler that bypasses the HTTP path. **Rejected** because it would diverge the auth/audit trail — both surfaces should land in the same `ApprovalsTable` row with the same fields.

## Acceptance criteria

- [ ] Operator who is logged into Slack via the existing `link account` flow can approve / deny a pending task by clicking a button in the FanOut-dispatched Slack message
- [ ] Approval row in `TaskApprovalsTable` shows `decided_by_channel: "slack"` (new optional field — extends the existing schema additively)
- [ ] Slack button click is rejected (with a friendly Slack ephemeral message) if the clicker is not the task owner — same 403 logic as the HTTP handler
- [ ] CDK unit tests cover both new action_ids; CDK construct tests verify the FanOut config
- [ ] Updated user docs section in `docs/guides/USER_GUIDE.md` showing the Slack approval flow

## Out of scope

- iOS / Android push notifications.
- Mobile-friendly approval landing page (web-form fallback for users not on Slack).
- Reassigning a stuck approval to a different user (separate issue if needed).
- Bulk approve/deny.

## References

- `cdk/src/constructs/slack-integration.ts`
- `cdk/src/handlers/slack-interactions.ts` (existing block_actions handler)
- `cdk/src/handlers/shared/slack-blocks.ts` (Block Kit template helpers)
- `cdk/src/handlers/approve-task.ts` / `deny-task.ts` (existing approval handlers)
- `docs/design/CEDAR_HITL_GATES.md` §6.5 (approval flow design)
- Slack Block Kit reference:

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza con cdk/src/handlers/slack-interactions.ts, shared/slack-blocks.ts, slack-notify.ts y approve-task.ts/deny-task.ts; ejecuta cdk/test/handlers/slack-interactions.test.ts para entender la cobertura existente de block_actions. Traza el flujo de aprobación actual y el comportamiento compartido de autorización antes de añadir la ruta de Slack. Se considera terminado cuando estén cubiertos ambos IDs de acción, los bloques de notificación de Slack, la atribución del canal, el rechazo del propietario, la cobertura del construct, la validación E2E y la sección de USER_GUIDE.md.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
aws, typescript
Área
api, backend, devops, documentation, testing
Tipo de issue
Nueva funcionalidad
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bien especificado
Aptitud para principiantes
48/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.