security: add authorization checks to WorkflowHttpHandler#16156
security: add authorization checks to WorkflowHttpHandler#16156adilburaksen wants to merge 1 commit into
Conversation
The workflow run endpoints under
/v3/namespaces/{namespace-id}/apps/{app-id}/workflows/{workflow-id}/runs/{run-id}
read workflow run data (workflow token, node-level token, node states,
local datasets) and changed workflow run state (suspend, resume, delete
local datasets) using only the namespace, application and workflow names
supplied in the request path, without enforcing any access control on
the selected workflow program. A caller could therefore read run data
from, or change the run state of, workflow programs it is not authorized
to access.
Enforce access on the workflow ProgramReference via the injected
ContextAccessEnforcer before each read or state change: StandardPermission.GET
for the read endpoints and StandardPermission.UPDATE for the state-changing
endpoints, mirroring the program-level enforcement already performed by the
sibling program runtime handler.
There was a problem hiding this comment.
Code Review
This pull request integrates authorization checks into WorkflowHttpHandler by injecting ContextAccessEnforcer and enforcing permissions (UPDATE or GET) across various workflow endpoints. However, a critical compilation issue was identified: the contextAccessEnforcer.enforce method throws a checked exception (AccessException), but enforceWorkflowAccess and several calling endpoints do not declare or handle this exception, which will prevent the code from compiling.
| private void enforceWorkflowAccess(String namespaceId, String appId, String workflowId, | ||
| StandardPermission permission) { | ||
| ProgramReference programReference = Ids.namespace(namespaceId).appReference(appId) | ||
| .program(ProgramType.WORKFLOW, workflowId); | ||
| contextAccessEnforcer.enforce(programReference, permission); | ||
| } |
There was a problem hiding this comment.
The contextAccessEnforcer.enforce method throws AccessException, which is a checked exception. However, enforceWorkflowAccess does not declare throws AccessException (or throws Exception) or catch it, which will cause a compilation error.
To resolve this, enforceWorkflowAccess should be updated to declare throws Exception (or throws AccessException). Additionally, all calling endpoint methods that do not already declare throws Exception (such as getWorkflowToken, getWorkflowNodeStates, getWorkflowLocalDatasets, and deleteWorkflowLocalDatasets) must also be updated to declare throws Exception in their method signatures to propagate the exception correctly.
| private void enforceWorkflowAccess(String namespaceId, String appId, String workflowId, | |
| StandardPermission permission) { | |
| ProgramReference programReference = Ids.namespace(namespaceId).appReference(appId) | |
| .program(ProgramType.WORKFLOW, workflowId); | |
| contextAccessEnforcer.enforce(programReference, permission); | |
| } | |
| private void enforceWorkflowAccess(String namespaceId, String appId, String workflowId, | |
| StandardPermission permission) throws Exception { | |
| ProgramReference programReference = Ids.namespace(namespaceId).appReference(appId) | |
| .program(ProgramType.WORKFLOW, workflowId); | |
| contextAccessEnforcer.enforce(programReference, permission); | |
| } |
The workflow run endpoints under
/v3/namespaces/{namespace-id}/apps/{app-id}/workflows/{workflow-id}/runs/{run-id}accessed workflow run data and workflow run state using only the namespace, application and workflow names from the request path, without enforcing any access control on the selected workflow program.This change injects
ContextAccessEnforcerinto the handler and enforces access on the workflowProgramReferencebefore each operation:StandardPermission.GET.StandardPermission.UPDATE.This mirrors the program-level enforcement already performed by the sibling program runtime handler and the other authorization PRs in this area. Hardening only; no functional change for authorized callers.