Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security solution] Implement dashboard to track Gen AI Token Usage #159075

Merged
merged 79 commits into from
Jun 15, 2023

Conversation

stephmilovic
Copy link
Contributor

@stephmilovic stephmilovic commented Jun 5, 2023

Summary

Resolves https://github.com/elastic/security-team/issues/6712

  1. Implements new gen ai subaction called getDashboard. The subaction checks if a dashbord with a given id exists, and if not creates the dashboard. Returns { exists: true } upon successful retreival/creation
  2. The subaction also checks the users permissions on the index pattern used by the dashboard, and will return { exists: false } if the user does not have permissions.
  3. When the getDashboard subaction returns { exists: true } and isEdit is true, the connector form displays a link to the dashboard filtered by the connector id
Screenshot 2023-06-05 at 5 17 46 PM Screenshot 2023-06-05 at 5 21 09 PM

Type confusion

It seems the stack_connectors uses the triggers_actions_ui CONNECTORS_PLUGIN_ID which has its own TriggersAndActionsUiServices type. However, when I import useKibana it is tied to the type for PLUGIN_ID. That is why I extended both versions of the app to include dashboard. Please let me know if you think I should instead maybe export a useKibana that is specifically typed to the connector?

To test

Credentials for OpenAI and Azure OpenAI: https://p.elstc.co/paste/+6nHnsHt#WJOOGIkVoJjTq7zPLP77BzSG1AUxNFUDvcnSfLPtO7m

  1. Create at least two GenAI connectors with OpenAI or Azure OpenAI credentials
  2. Create multiple users
  3. Log in with each user and send a variety of prompts using the "Test" panel for each connector
  4. Open one of the connectors and click the new link to dashboard
  5. Confirm that the different users token usage is reflected
  6. Confirm that the view is filtered to the connector id:
Screenshot 2023-06-05 at 5 29 50 PM 8. Remove the filter, confirm that the Lens charts reflect that change and shows usage for both of your connectors

Testing permissions

  1. Create a user with the "Viewer" role.
  2. Login with that user and open a Gen AI connector edit view in stack management
  3. Notice that the link to the dashboard is not there

Update 6/12/23: Updated to selectively show the link to the dashboard based on user permissions
Update 6/13/23: Added a markdown text block to explain dashboard permissions, content to be updated with a doc link
Screenshot 2023-06-13 at 11 09 58 AM

@stephmilovic stephmilovic added release_note:enhancement Team:Threat Hunting Security Solution Threat Hunting Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. labels Jun 5, 2023
Copy link
Member

@pmuellr pmuellr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Made a few requests to changes to the logging and some tests.

body: {
index: [
{
names: ['*.kibana-event-log-*'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We definitely should not use * at the beginning, Could have been done because the new index names of the datastream-y event log are: .ds-.kibana-event-log-8.9.0-2023.06.12-000001 - but I just tried, and this API seems to do the right thing when using .kibana-event-log-* - presumably checking the data stream.

body: {
index: [
{
names: ['*.kibana-event-log-*'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of a fuzzy line - I was also a little surprised this was a subcommand and not an internal route. Technically, I don't think there's much of a difference. To some extent, subcommands are "managed" in the code a little better than routes, that sometimes end up in odd places. And less ceremony, and chances that we got the auth wrong in the route, etc.

I think the thing that separates this from things like Jira, is that this subcommand doesn't really do anything with the connector. It literally could be a stand-alone route, anywhere. It doesn't NEED to be in the connector.

The other aspect is backwards compatibility. We consider connectors to be API, so we would have to support this subcommand forever. The chances that someone would use this externally seem low, but customers are crafty, and someone doing infrastructure-as-code might realize what's going on, and bake this into some scripts of theirs. Which would then break their scripts when we remove it. The chances of that happening with an internal HTTP API seems smaller.

Risk seems very low with this one, especially if this is temporary. If we don't think it's temporary, converting to an internal route after FF next week is a possibility as well.

const setUrl = useCallback(
(dashboardId: string) => {
const url = dashboard?.locator?.getRedirectUrl({
query: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nice enhancement for later would be looking into making this one of the "pilled" filter thingees, instead of the query. That would leave the query empty for customers to do further querying without having to worry about the connector match clause. Not actually sure that's possible, but think it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, i will research that further

@stephmilovic
Copy link
Contributor Author

We definitely should not use * at the beginning, Could have been done because the new index names of the datastream-y event log are: .ds-.kibana-event-log-8.9.0-2023.06.12-000001 - but I just tried, and this API seems to do the right thing when using .kibana-event-log-* - presumably checking the data stream.

@pmuellr re: #159075 (comment)

Yeah I felt weird about that too, but my original approach I had used a index method I found in being used to match indices in triggers_actions_ui. getMatchingIndices will prepend a * to the index, so I thought that was how y'all preferred things. I'd suggest adjusting this method so it does not get copied around more, or add a comment explaining why it is being done there and why we should not be copying it?

I will remove it on my code for sure

@pmuellr
Copy link
Member

pmuellr commented Jun 14, 2023

Yeah I felt weird about that too, but my original approach I had used a index method I found in being used to match indices in triggers_actions_ui. getMatchingIndices will prepend a * to the index, so I thought that was how y'all preferred things. I'd suggest adjusting this method so it does not get copied around more, or add a comment explaining why it is being done there and why we should not be copying it?

Ah! Ya, that code is for users searching through their own indices. I think the feeling was a the time, if they typed acme in a text field, we should match something-acme-other, and the only way to do that is to prepend/append the *. For this code though, we're looking for specific names.

If you're not all finished, wanna add a comment yourself? Else I will do a quick one. Suggestion:

// prepend and append index search requests with `*` to match the given text in middle of index names

@stephmilovic
Copy link
Contributor Author

@elasticmachine merge upstream

@@ -41,7 +41,7 @@ export class ObjectRemover {
`${getUrlPrefix(spaceId)}/${isInternal ? 'internal' : 'api'}/${plugin}/${type}/${id}`
)
.set('kbn-xsrf', 'foo')
.expect(204);
.expect(plugin === 'saved_objects' ? 200 : 204);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm deleting a saved object, and the successful response for this api is 200

Copy link
Member

@pmuellr pmuellr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
stackConnectors 202 204 +2

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
actions 259 261 +2
triggersActionsUi 518 519 +1
total +3

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
stackConnectors 449.8KB 457.4KB +7.6KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
stackConnectors 34.7KB 34.7KB +27.0B
triggersActionsUi 85.6KB 85.6KB +44.0B
total +71.0B
Unknown metric groups

API count

id before after diff
actions 264 266 +2
triggersActionsUi 544 545 +1
total +3

ESLint disabled line counts

id before after diff
enterpriseSearch 13 15 +2
securitySolution 410 414 +4
total +6

Total ESLint disabled count

id before after diff
enterpriseSearch 14 16 +2
securitySolution 493 497 +4
total +6

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@stephmilovic stephmilovic enabled auto-merge (squash) June 15, 2023 18:23
Copy link
Contributor

@angorayc angorayc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done! Thank you Steph! LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting release_note:enhancement Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Threat Hunting:Explore Team:Threat Hunting Security Solution Threat Hunting Team v8.9.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants