Skip to content

Commit

Permalink
[Obs AI Assistant] Add security configs to API (elastic#201439)
Browse files Browse the repository at this point in the history
## Summary

### Problem
The API
`/internal/observability/assistant/alert_details_contextual_insights`
does not provide explicit authorization settings.

### Solution
Add access privileges (`ai_assistant`) to the above API

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
  • Loading branch information
viduni94 authored and CAWilson94 committed Dec 12, 2024
1 parent 10e8082 commit 724a3b2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ import { createObservabilityServerRoute } from '../create_observability_server_r
const getObservabilityAlertDetailsContextRoute = createObservabilityServerRoute({
endpoint: 'GET /internal/observability/assistant/alert_details_contextual_insights',
options: {
tags: [],
access: 'internal',
},
security: {
authz: {
requiredPrivileges: ['ai_assistant'],
},
},
params: t.type({
query: alertDetailsContextRt,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface ObservabilityRouteHandlerResources {
}

export interface ObservabilityRouteCreateOptions {
tags: string[];
tags?: string[];
access?: 'public' | 'internal';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default function ApiTest({ getService }: ObsFtrProviderContext) {
const obsApiClient = getService('obsApiClient');
const apmSynthtraceClient = getService('apmSynthtraceEsClient');
const logSynthtraceClient = getService('logSynthtraceEsClient');
const security = getService('security');
const supertestWithoutAuth = getService('supertestWithoutAuth');

describe('fetching observability alerts details context for AI assistant contextual insights', () => {
const start = moment().subtract(10, 'minutes').valueOf();
Expand Down Expand Up @@ -511,5 +513,39 @@ export default function ApiTest({ getService }: ObsFtrProviderContext) {
await apmSynthtraceClient.clean();
await logSynthtraceClient.clean();
}

describe('security roles and access privileges', () => {
it('is not available to unauthorized users', async () => {
const UNAUTHORIZED_USERNAME = 'UNAUTHORIZED_USER';
const UNAUTHORIZED_USER_PASSWORD = 'UNAUTHORIZED_USER_PASSWORD';

// Create a user with no privileges
await security.user.create(UNAUTHORIZED_USERNAME, {
password: UNAUTHORIZED_USER_PASSWORD,
roles: [],
full_name: 'Unauthorized Test User',
});

try {
// Make a request to the target API with insufficient privileges
await supertestWithoutAuth
.get('/internal/observability/assistant/alert_details_contextual_insights')
.auth(UNAUTHORIZED_USERNAME, UNAUTHORIZED_USER_PASSWORD)
.query({ alertId: 'test-alert-id' })
.set('kbn-xsrf', 'true')
.expect(403)
.then(({ body }: any) => {
expect(body).to.eql({
statusCode: 403,
error: 'Forbidden',
message:
'API [GET /internal/observability/assistant/alert_details_contextual_insights?alertId=test-alert-id] is unauthorized for user, this action is granted by the Kibana privileges [ai_assistant]',
});
});
} finally {
await security.user.delete(UNAUTHORIZED_USERNAME);
}
});
});
});
}

0 comments on commit 724a3b2

Please sign in to comment.