Skip to content

feat: add task-level authorization hook#29

Merged
maxekman merged 1 commit intoactioncard:mainfrom
dgilperez:feat/task-access-control
May 4, 2026
Merged

feat: add task-level authorization hook#29
maxekman merged 1 commit intoactioncard:mainfrom
dgilperez:feat/task-access-control

Conversation

@dgilperez
Copy link
Copy Markdown
Contributor

Summary

  • add an optional :authorize_task callback to A2A.Plug for task-scoped access control
  • authorize tasks/get and tasks/cancel before returning or mutating tasks, using TaskNotFoundError for denials to avoid task ID leakage
  • filter tasks/list responses through the same hook and document the remaining store-level pagination hardening path

Why

The A2A spec requires servers not to reveal resources the client is not authorized to access. This gives Plug users a focused hook for tenant/user task ownership checks without changing storage implementations.

Verification

  • mix test
  • mix quality
  • bin/tck mandatory

@maxekman
Copy link
Copy Markdown
Contributor

maxekman commented May 4, 2026

Related to #19.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

TCK Compliance Results

📊 COMPREHENSIVE TEST RESULTS SUMMARY
================================================================================

🔴 Mandatory Tests:           ✅ PASSED (p:83/f:0/x:0/e:0/s:32)
🔄 Capability Tests:          ✅ PASSED (p:20/f:0/x:1/e:0/s:54)
🚀 Transport Equivalence:     ✅ PASSED (p:0/f:0/x:0/e:0/s:16)
🛡️  Quality Tests:             ✅ PASSED (p:14/f:0/x:0/e:0/s:0)
🎨 Feature Tests:             ✅ PASSED (p:14/f:0/x:1/e:0/s:1)

🎉 A2A COMPLIANCE: ✅ PASSED
Your implementation meets A2A specification requirements!
🔄 CAPABILITY HONESTY: ✅ EXCELLENT
All declared capabilities work correctly!
🛡️  PRODUCTION QUALITY: ✅ HIGH
Implementation is robust and production-ready!
🎨 FEATURE COMPLETENESS: ✅ COMPREHENSIVE
Implementation includes valuable optional features!

🏆 OUTSTANDING A2A IMPLEMENTATION!

================================================================================

========================================
TCK run complete.
Stopping server (PID 2583)...

07:03:44.120 [notice] SIGTERM received - shutting down

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

TCK 1.0-dev Compatibility Results (experimental)

This run is informational — failures do not block CI.

             A2A TCK Compatibility Report              
═══════════════════════════════════════════════════════
SUT: http://localhost:9999
Timestamp: 2026-05-04T07:03:31.128683+00:00

OVERALL COMPATIBILITY: 43.3%

┌─────────────┬────────┬────────┬─────────┬───────┐
│ Level       │ Passed │ Failed │ Skipped │ Total │
├─────────────┼────────┼────────┼─────────┼───────┤
│ MUST        │     25 │     54 │      35 │   114 │
│ SHOULD      │      2 │      9 │       0 │    11 │
│ MAY         │      2 │      2 │       0 │     4 │
└─────────────┴────────┴────────┴─────────┴───────┘

BY TRANSPORT:
  agent_card:    7/10 ⚠
  grpc:          0/72 (72 skipped) ✓
  jsonrpc:       28/99 (30 skipped) ⚠
  http_json:     3/83 (80 skipped) ✓

FAILED REQUIREMENTS:
  ✗ CARD-STRUCT-001 (): $: 'url' does not match any of the regexes: '^(default_input_modes)$', '^(default_output_modes)$', '^(documentation_url)$', '^(icon_url)$', '^(security_requirements)$', '^(security_schemes)$', '^(supported_interfaces)$'
  ✗ CARD-CACHE-002 (agent_card): Agent Card response should include an ETag header
  ✗ CARD-CACHE-003 (agent_card): Agent Card response may include a Last-Modified header
  ✗ DM-ART-001 (jsonrpc): Response contains no artifacts
  ✗ DM-MSG-001 (jsonrpc): Expected a Message response, but got a Task or no payload
  ✗ DM-TASK-001 (jsonrpc): $.task: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ DM-TASK-002 (jsonrpc): $.task: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ DM-MSG-002 (jsonrpc): $.task: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ DM-PART-001 (jsonrpc): $.task: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ DM-STATUS-001 (jsonrpc): $.task: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ DM-SERIAL-004 (jsonrpc): $.task: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ VER-SERVER-002 (jsonrpc): Expected VersionNotSupportedError for A2A-Version: 99.0
  ✗ JSONRPC-SSE-002 (): Error code mismatch: expected ContentTypeNotSupportedError (-32005), got ParseError (-32700)
  ✗ JSONRPC-ERR-003 (): error.data is absent — A2A errors MUST include ErrorInfo in data array
  ✗ CORE-SEND-001 (jsonrpc): $.task: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ CORE-SEND-003 (jsonrpc): Operation failed: Invalid parameters
  ✗ CORE-LIST-001 (jsonrpc): $.tasks[0]: 'kind' does not match any of the regexes: '^(context_id)$'
  ✗ CORE-LIST-002 (jsonrpc): $.tasks[0]: 'kind' does not match any of the regexes: '^(context_id)$'

@maxekman maxekman merged commit 5d64f61 into actioncard:main May 4, 2026
8 checks passed
@maxekman
Copy link
Copy Markdown
Contributor

maxekman commented May 4, 2026

Thanks for the contribution @dgilperez!

@dgilperez dgilperez deleted the feat/task-access-control branch May 4, 2026 10:16
@dgilperez
Copy link
Copy Markdown
Contributor Author

Nice! Happy to push this :)

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