* fix(identity): route the remaining permission checks through the evaluator Completes T038 of the authorization model, and fixes a live defect it was meant to catch. RoleDeletionCoordinator.InspectAsync gated on the legacy string "delete:role", compared by claim-value equality. Nothing has granted that spelling since the vocabulary migration, so a caller holding identity/roles:delete passed the endpoint's own RequirePermission check and was then refused mid-handler by the coordinator. In practice role deletion worked only for holders of "*", across all three routes that reach the coordinator (Delete, RemediateAndDelete and GetDeletionImpact). The check now evaluates identity/roles:delete through PermissionEvaluator, so structured and wildcard grants both reach it. Every existing coordinator test acted as an administrator holding "*", which is why this went unnoticed; the added cases exercise identity/roles:delete, identity/*:delete and identity/roles:* and assert an unrelated grant is still refused. AIHttpContextIdentity matched an agent's required permissions by case-insensitive exact-set containment, which both admitted casing the rest of the model rejects and refused the wildcards it honours. It now evaluates each required permission through the same evaluator. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(ai): restore the null-safe HttpContext access in the tools endpoint The tools endpoint dereferenced HttpContext directly when passing the principal to GetAuthorizedAgent, which threw a NullReferenceException and failed two Elsa.AI.IntegrationTests cases on CI. This was collateral from tightening a nullable warning in the chat endpoint. The chat endpoint dereferences HttpContext.Response unconditionally a few lines later, so HttpContext.User is safe there; the tools endpoint never does, and its three sibling calls -- GetPermissions, GetActorId and GetTenantId -- all accept a null context. The same edit was applied to both, and only chat could take it. Reverting to HttpContext?.User preserves the endpoint's prior behaviour: GetAuthorizedAgent treats a null principal as holding nothing, and an agent that declares no required permissions stays authorized either way, because the empty-requirements check runs before the null check. Elsa.AI.IntegrationTests 69/69 (was 67 passed, 2 failed); Elsa.Identity.UnitTests 115/115; Elsa.AI.Host builds with no CS8602. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| Context | ||
| Endpoints/AI | ||
| Extensions | ||
| Features | ||
| Options | ||
| Permissions | ||
| Services | ||
| ShellFeatures | ||
| Streaming | ||
| Tools | ||
| Elsa.AI.Host.csproj | ||
| README.md | ||
| Usings.cs | ||
Elsa AI Host
Elsa AI Host owns Weaver's provider-neutral server surface: chat orchestration, context resolution, tool registration, proposal governance, audit, and Studio-facing capabilities. Provider SDK types stay outside this module.
Grounding Tools
Built-in grounding tools are registered as IAITool implementations. Read-only tools are enabled by default; proposal tools must be enabled explicitly before a provider can invoke them.
Activity tools:
activities.searchactivities.getDescriptor
Workflow definition tools:
workflows.searchworkflows.getDefinitionworkflows.getDefinitionGraphworkflows.findUsages
Proposal-only tools:
workflows.validateDraftworkflows.proposeCreateworkflows.proposeUpdate
Runtime inspection tools:
instances.searchinstances.getinstances.getExecutionHistoryinstances.getActivityStateincidents.searchincidents.get
The tools read from Elsa server-side sources such as IActivityRegistry, IWorkflowDefinitionStore, and IWorkflowInstanceStore. If a source is not registered, the tool returns an unavailable result and /ai/capabilities reports the disabled reason for Studio.
All tool results are bounded by AIHostOptions.Grounding, redacted before returning to the model or Studio, and audited by the existing AI Host tool invocation path.
Proposal Safety
workflows.proposeCreate and workflows.proposeUpdate write only to IAIProposalStore. They do not persist workflow definitions. Approval and apply remain separate governed actions.