CCC: Refactor to harden function-call plugin / runtime surface (GetAiRelevantContext)
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3574910. --> Reported by: [kristen pol](https://www.drupal.org/user/8389) >>> <p>[Tracker]<br> <strong>Update Summary: </strong>[One-line status update for stakeholders]<br> <strong>Check-in Date: </strong>MM/DD/YYYY<br> <strong>Blocked by: </strong>[#XXXXXX] (New issues on new lines)<br> <strong>Additional Collaborators: </strong> @username1, @username2<br> <em>Metadata is used by the <a href="https://www.drupalstarforge.ai/" title="AI Tracker">AI Tracker.</a> Docs and additional fields <a href="https://www.drupalstarforge.ai/ai-dashboard/docs" title="AI Issue Tracker Documentation">here</a>.</em><br> [/Tracker]</p> <h3 id="summary-problem-motivation">Problem/Motivation</h3> <p>Follow-up to:</p> <p><span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/ai_context/issues/3573713" title="Status: Closed (fixed)">#3573713: Full architecture review of CCC in prep for 1.0</a></span></p> <p><strong>Summary / goal</strong></p> <p>Add authorization and structured logging around the FunctionCall plugin that exposes context selection (GetAiRelevantContext) so only authorized runtimes/callers can invoke it and calls are auditable.</p> <p><strong>Why this matters</strong></p> <p>GetAiRelevantContext exposes site context programmatically. Without caller validation it can be used to enumerate sensitive content or be invoked by untrusted runtimes. Adding auth + logging prevents abuse and improves traceability.</p> <p><strong>Acceptance criteria</strong></p> <ul> <li>Unauthorized callers are rejected (unit tests simulate unauthorized caller -&gt; plugin returns error/throws or no data).</li> <li>Every successful invocation logs a structured audit entry including caller identity (user id or service id), agent_id, runner_id if provided, and request route/context.</li> <li>Backwards-compatible: existing trusted runtimes still work when configured (clear migration path).</li> <li>Tests verify both rejection and successful logged entries.</li> </ul> <h3 id="summary-proposed-resolution">Proposed resolution</h3> <p><strong>Primary files</strong></p> <ul> <li>src/Plugin/AiFunctionCall/GetAiRelevantContext.php</li> </ul> <p><strong>Recommended implementation approach (directional)</strong></p> <ul> <li>Decide caller identity model: prefer server-side caller identity (current user / service account / API key) or host runtime-provided token. Document expected caller (e.g., internal agent runtime vs external).</li> <li>Add an explicit permission check or runtime-auth check early in the plugin: <ul> <li>If invoked in HTTP request context, check current user permissions (view ai context items or a new invoke ai_context function permission).</li> <li>If invoked by non-user runtimes, require a configured runtime token or allowlist and validate it via RequestStack or a configured auth service.</li> </ul> </li> <li>Add structured logging (PSR-3) with placeholders: plugin id, agent_id, caller_id, runner_id, number of selected IDs, and duration. Use logger channel ai_context and avoid logging full context content.</li> <li>Optionally add simple rate-limiting or quota checks per caller if discovery abuse is a concern.</li> </ul> <p><strong>Subtasks</strong></p> <ol> <li>[Decision] Choose caller auth model (permission vs runtime token/allowlist) and document behavior.</li> <li>Implement auth check in plugin (inject current_user / requestStack / auth service) and return safe error on unauthorized calls.</li> <li>Add structured logging of each call (success/failure) with minimal safe fields.</li> <li>Add unit tests for authorized and unauthorized scenarios.</li> <li>Update docs/README noting plugin security expectations and config.</li> </ol> <p><strong>Testing strategy</strong></p> <ul> <li>Unit tests that instantiate the plugin with mocked container and simulate:</li> <li>Authorized caller: plugin executes and returns expected IDs/text; logger called with expected fields.</li> <li>Unauthorized caller: plugin denies access (exception or empty result) and logs the denied attempt.</li> <li>Integration test for host runtime scenario (if applicable) to verify configured token is accepted.</li> </ul> <p><strong>Risks &amp; mitigations</strong></p> <ul> <li>Risk: Breaking existing integrations if auth model changes. Mitigate by supporting dual-mode (legacy allowed via config flag) and communicating change.</li> <li>Risk: Overlogging sensitive text. Mitigate by logging metadata only (IDs, counts, caller id) and never full context content or prompt text.</li> </ul> <h3 id="summary-remaining-tasks">Target date or deadline</h3> <p>February 2026</p> <h3 id="summary-remaining-tasks">Remaining tasks</h3> <ul> <li>Review AI findings</li> <li>Decide if they are correct</li> <li>Decide if the proposed approach is best or propose alternative</li> <li>Update code</li> <li>Review and test</li> </ul> <h3 id="summary-ai-usage">AI usage (if applicable)</h3> <p>[x] AI Assisted Issue<br> This issue was generated with AI assistance, but was reviewed and refined by the creator.</p> <p>[ ] AI Assisted Code<br> This code was mainly generated by a human, with AI autocompleting or parts AI generated, but under full human supervision.</p> <p>[ ] AI Generated Code<br> This code was mainly generated by an AI with human guidance, and reviewed, tested, and refined by a human.</p> <p>[ ] Vibe Coded<br> This code was generated by an AI and has only been functionally tested.</p> > Related issue: [Issue #3573713](https://www.drupal.org/node/3573713)
issue