Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions icp_server/observability_service.bal
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// specific language governing permissions and limitations
// under the License.

import icp_server.auth;
import icp_server.storage as storage;
import icp_server.types as types;

Expand Down Expand Up @@ -121,6 +122,31 @@ isolated function initObservabilityClient() returns http:Client? {
return httpClient;
}

// Caller must run after HTTP JWT validation (Authorization present and signature verified).
isolated function extractUserFromObservabilityRequest(http:Request request) returns types:UserContextV2|error {
string|http:HeaderNotFoundError authHeader = request.getHeader("Authorization");
if authHeader is http:HeaderNotFoundError {
return error("Authorization header missing");
}
return auth:extractUserContextV2(authHeader);
}

// Restrict resolved runtimes to those the user may access (integration + environment scope).
isolated function filterRuntimeIdsForUser(string userId, string[] runtimeIds) returns string[]|error {
log:printDebug("Filtering runtime IDs for user", userId = userId, runtimeCount = runtimeIds.length());
string[] filtered = [];
Comment thread
sakith03 marked this conversation as resolved.
foreach string rid in runtimeIds {
boolean|error allowed = storage:hasAccessToRuntime(userId, rid);
if allowed is error {
return allowed;
}
if allowed {
filtered.push(rid);
}
}
return filtered;
}

@http:ServiceConfig {
auth: [
{
Expand Down Expand Up @@ -155,6 +181,10 @@ service /icp/observability on httpListener {
environmentList: logRequest.environmentList
});

types:UserContextV2 userContext = check extractUserFromObservabilityRequest(request);
log:printInfo("Processing logs request", userId = userContext.userId);
runtimeIdList = check filterRuntimeIdsForUser(userContext.userId, runtimeIdList);
Comment thread
sakith03 marked this conversation as resolved.

// If component/environment filters were provided but no runtimes found, return empty result
boolean hasFilters = logRequest.componentId is string ||
(logRequest.componentIdList is string[] && (<string[]>logRequest.componentIdList).length() > 0) ||
Expand Down Expand Up @@ -238,6 +268,9 @@ service /icp/observability on httpListener {
environmentList: metricRequest.environmentList
});

types:UserContextV2 userContext = check extractUserFromObservabilityRequest(request);
runtimeIdList = check filterRuntimeIdsForUser(userContext.userId, runtimeIdList);

// If component/environment filters were provided but no runtimes found, return empty result
boolean hasFilters = metricRequest.componentId is string ||
(metricRequest.componentIdList is string[] && (<string[]>metricRequest.componentIdList).length() > 0) ||
Expand Down
Loading