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] AWS Bedrock connector #166662

Merged
merged 54 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
00cdab0
wip
stephmilovic Sep 13, 2023
f907c46
Merge branch 'main' into bedrock
stephmilovic Sep 18, 2023
45bb251
bootstrapping
stephmilovic Sep 18, 2023
70c470f
working
stephmilovic Sep 18, 2023
9f6c8fe
fix
stephmilovic Sep 18, 2023
182d90e
fix url
stephmilovic Sep 18, 2023
75ae921
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Sep 18, 2023
c55a851
connector added to AI assistant
stephmilovic Sep 19, 2023
16902ca
Merge branch 'bedrock' of github.com:stephmilovic/kibana into bedrock
stephmilovic Sep 19, 2023
40ab64d
fix
stephmilovic Sep 19, 2023
e461297
dentist
stephmilovic Sep 19, 2023
4f3019c
invokeAI method
stephmilovic Sep 20, 2023
5991de8
rm log
stephmilovic Sep 20, 2023
be72b79
Merge branch 'main' into bedrock
stephmilovic Sep 20, 2023
e90395e
make langchain work
stephmilovic Sep 20, 2023
e884b94
about to combine connector selector components
stephmilovic Sep 20, 2023
f6aa152
condense connector selector logic
stephmilovic Sep 20, 2023
95f5a97
undo type change
stephmilovic Sep 20, 2023
90dfe25
remove dashboard and fix types
stephmilovic Sep 20, 2023
c5c65f7
fix stack_connectors tests
stephmilovic Sep 20, 2023
ed4773b
Merge branch 'main' into bedrock
stephmilovic Sep 20, 2023
1c61a59
aws4 package instead of aws4-axios
stephmilovic Sep 20, 2023
3863f09
fix type and lint
stephmilovic Sep 20, 2023
36065f8
fix test
stephmilovic Sep 20, 2023
b7a8923
add aws region
stephmilovic Sep 21, 2023
f3257a0
fix stack connectors tests
stephmilovic Sep 21, 2023
f976db6
add bedrock api tests
stephmilovic Sep 21, 2023
16f78ca
add docs
stephmilovic Sep 21, 2023
6cc29a1
remove a .only whoops
stephmilovic Sep 21, 2023
3ff4aa4
FIXES
stephmilovic Sep 21, 2023
2585ec1
test fix
stephmilovic Sep 21, 2023
6783179
more fixing
stephmilovic Sep 21, 2023
2d57ffb
Merge branch 'main' into bedrock
stephmilovic Sep 21, 2023
c203549
fix tests on security side
stephmilovic Sep 21, 2023
edf8430
fix img address and add comments to ai subactions
stephmilovic Sep 21, 2023
9594572
Merge branch 'main' into bedrock
angorayc Sep 24, 2023
ad54ca9
fix test
stephmilovic Sep 25, 2023
79ec175
Merge branch 'bedrock' of github.com:stephmilovic/kibana into bedrock
stephmilovic Sep 25, 2023
da40bfb
Merge branch 'main' into bedrock
stephmilovic Sep 25, 2023
f310ac7
fix host protocol
stephmilovic Sep 25, 2023
d0549eb
Merge branch 'main' into bedrock
stephmilovic Sep 25, 2023
4acbbc5
fix merge
stephmilovic Sep 25, 2023
11ae8d7
add model to params form
stephmilovic Sep 25, 2023
c6d7e94
pr updates for ymao1
stephmilovic Sep 26, 2023
30f93cc
rm console log
stephmilovic Sep 26, 2023
ac8eb76
the logo is here!
stephmilovic Sep 27, 2023
9b872df
Merge branch 'main' into bedrock
stephmilovic Sep 27, 2023
ded3418
Merge branch 'main' into bedrock
kibanamachine Sep 27, 2023
bcb1c14
Merge branch 'main' into bedrock
kibanamachine Sep 27, 2023
7492595
update screenshots
stephmilovic Sep 27, 2023
2f88749
Merge branch 'main' into bedrock
kibanamachine Sep 27, 2023
7ef8a09
Merge branch 'main' into bedrock
kibanamachine Sep 27, 2023
5b58a3a
Merge branch 'main' into bedrock
kibanamachine Sep 27, 2023
ae9856e
Merge remote-tracking branch 'upstream/main' into bedrock
stephmilovic Sep 27, 2023
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
12 changes: 8 additions & 4 deletions docs/management/action-types.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ Connectors provide a central place to store connection information for services
[cols="2"]
|===

a| <<bedrock-action-type,AWS Bedrock>>

| Send a request to AWS Bedrock.

a| <<d3security-action-type,D3 Security>>

| Send a request to D3 Security.
Expand All @@ -15,10 +19,6 @@ a| <<email-action-type,Email>>

| Send email from your server.

a| <<gen-ai-action-type,Generative AI>>

| Send a request to OpenAI.

a| <<resilient-action-type,{ibm-r}>>

| Create an incident in {ibm-r}.
Expand All @@ -35,6 +35,10 @@ a| <<teams-action-type,Microsoft Teams>>

| Send a message to a Microsoft Teams channel.

a| <<gen-ai-action-type,OpenAI>>

| Send a request to OpenAI.

a| <<opsgenie-action-type,{opsgenie}>>

| Create or close an alert in {opsgenie}.
Expand Down
68 changes: 68 additions & 0 deletions docs/management/connectors/action-types/bedrock.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[[bedrock-action-type]]
== AWS Bedrock connector and action
++++
<titleabbrev>AWS Bedrock</titleabbrev>
++++
:frontmatter-description: Add a connector that can send requests to AWS Bedrock.
:frontmatter-tags-products: [kibana]
:frontmatter-tags-content-type: [how-to]
:frontmatter-tags-user-goals: [configure]


The AWS Bedrock connector uses https://github.com/axios/axios[axios] to send a POST request to AWS Bedrock. The connector uses the <<execute-connector-api,run connector API>> to send the request.

[float]
[[define-bedrock-ui]]
=== Create connectors in {kib}

You can create connectors in *{stack-manage-app} > {connectors-ui}*. For example:

[role="screenshot"]
// TODO: need logo before screenshot
Copy link
Contributor Author

Choose a reason for hiding this comment

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

to do before merge

image::management/connectors/images/bedrock-connector.png[AWS Bedrock connector]

[float]
[[bedrock-connector-configuration]]
==== Connector configuration

AWS Bedrock connectors have the following configuration properties:

Name:: The name of the connector.
API URL:: The AWS Bedrock request URL.
Default model:: The GAI model for AWS Bedrock to use. Current support is for the Anthropic Claude models, defaulting to Claude 2. The model can be set on a per request basis by including a "model" parameter alongside the request body.
Region:: The AWS Bedrock request URL.
Access Key:: The AWS access key for authentication.
Secret:: The secret for authentication.

[float]
[[bedrock-action-configuration]]
=== Test connectors

You can test connectors with the <<execute-connector-api,run connector API>> or
as you're creating or editing the connector in {kib}. For example:

[role="screenshot"]
// TODO: need logo before screenshot
image::management/connectors/images/bedrock-params.png[AWS Bedrock params test]

The AWS Bedrock actions have the following configuration properties.

Body:: A stringified JSON payload sent to the AWS Bedrock Invoke Model API URL. For example:
+
[source,text]
--
{
body: JSON.stringify({
prompt: `${combinedMessages} \n\nAssistant:`,
max_tokens_to_sample: 300,
stop_sequences: ['\n\nHuman:']
})
}
--
Model:: An optional string that will overwrite the connector's default model. For

[float]
[[bedrock-connector-networking-configuration]]
=== Connector networking configuration

Use the <<action-settings, Action configuration settings>> to customize connector networking configurations, such as proxies, certificates, or TLS settings. You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/management/connectors/images/gen-ai-connector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/management/connectors/index.asciidoc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include::action-types/bedrock.asciidoc[leveloffset=+1]
include::action-types/d3security.asciidoc[leveloffset=+1]
include::action-types/email.asciidoc[leveloffset=+1]
include::action-types/gen-ai.asciidoc[leveloffset=+1]
Expand Down
2 changes: 1 addition & 1 deletion docs/settings/alert-action-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ WARNING: This feature is available in {kib} 7.17.4 and 8.3.0 onwards but is not
A boolean value indicating that a footer with a relevant link should be added to emails sent as alerting actions. Default: true.

`xpack.actions.enabledActionTypes` {ess-icon}::
A list of action types that are enabled. It defaults to `["*"]`, enabling all types. The names for built-in {kib} action types are prefixed with a `.` and include: `.email`, `.index`, `.jira`, `.opsgenie`, `.pagerduty`, `.resilient`, `.server-log`, `.servicenow`, .`servicenow-itom`, `.servicenow-sir`, `.slack`, `.swimlane`, `.teams`, `.tines`, `.torq`, `.xmatters`, `.gen-ai`, `.d3security`, and `.webhook`. An empty list `[]` will disable all action types.
A list of action types that are enabled. It defaults to `["*"]`, enabling all types. The names for built-in {kib} action types are prefixed with a `.` and include: `.email`, `.index`, `.jira`, `.opsgenie`, `.pagerduty`, `.resilient`, `.server-log`, `.servicenow`, .`servicenow-itom`, `.servicenow-sir`, `.slack`, `.swimlane`, `.teams`, `.tines`, `.torq`, `.xmatters`, `.gen-ai`, `.bedrock`, `.d3security`, and `.webhook`. An empty list `[]` will disable all action types.
+
Disabled action types will not appear as an option when creating new connectors, but existing connectors and actions of that type will remain in {kib} and will not function.

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,7 @@
"antlr4ts": "^0.5.0-alpha.3",
"archiver": "^5.3.1",
"async": "^3.2.3",
"aws4": "^1.12.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

need to add aws4 module in order to sign requests to new AWS Bedrock connector. https://www.npmjs.com/package/aws4

"axios": "^1.4.0",
"base64-js": "^1.3.1",
"bitmap-sdf": "^1.0.3",
Expand Down Expand Up @@ -1272,6 +1273,7 @@
"@types/adm-zip": "^0.5.0",
"@types/archiver": "^5.3.1",
"@types/async": "^3.2.3",
"@types/aws4": "^1.5.0",
"@types/babel__core": "^7.20.0",
"@types/babel__generator": "^7.6.4",
"@types/babel__helper-plugin-utils": "^7.10.0",
Expand Down
62 changes: 6 additions & 56 deletions x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('fetchConnectorExecuteAction', () => {
expect(mockHttp.fetch).toHaveBeenCalledWith(
'/internal/elastic_assistant/actions/connector/foo/_execute',
{
body: '{"params":{"subActionParams":{"body":"{\\"model\\":\\"gpt-4\\",\\"messages\\":[{\\"role\\":\\"user\\",\\"content\\":\\"This is a test\\"}],\\"n\\":1,\\"stop\\":null,\\"temperature\\":0.2}"},"subAction":"test"}}',
body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"}}',
headers: { 'Content-Type': 'application/json' },
method: 'POST',
signal: undefined,
Expand All @@ -65,7 +65,7 @@ describe('fetchConnectorExecuteAction', () => {
await fetchConnectorExecuteAction(testProps);

expect(mockHttp.fetch).toHaveBeenCalledWith('/api/actions/connector/foo/_execute', {
body: '{"params":{"subActionParams":{"body":"{\\"model\\":\\"gpt-4\\",\\"messages\\":[{\\"role\\":\\"user\\",\\"content\\":\\"This is a test\\"}],\\"n\\":1,\\"stop\\":null,\\"temperature\\":0.2}"},"subAction":"test"}}',
body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"}}',
headers: { 'Content-Type': 'application/json' },
method: 'POST',
signal: undefined,
Expand All @@ -88,7 +88,7 @@ describe('fetchConnectorExecuteAction', () => {
});

it('returns API_ERROR when there are no choices', async () => {
(mockHttp.fetch as jest.Mock).mockResolvedValue({ status: 'ok', data: {} });
(mockHttp.fetch as jest.Mock).mockResolvedValue({ status: 'ok', data: '' });
const testProps: FetchConnectorExecuteAction = {
assistantLangChain: false,
http: mockHttp,
Expand All @@ -101,46 +101,12 @@ describe('fetchConnectorExecuteAction', () => {
expect(result).toBe(API_ERROR);
});

it('return the trimmed first `choices` `message` `content` when the API call is successful', async () => {
(mockHttp.fetch as jest.Mock).mockResolvedValue({
status: 'ok',
data: {
choices: [
{
message: {
content: ' Test response ', // leading and trailing whitespace
},
},
],
},
});

const testProps: FetchConnectorExecuteAction = {
assistantLangChain: false,
http: mockHttp,
messages,
apiConfig,
};

const result = await fetchConnectorExecuteAction(testProps);

expect(result).toBe('Test response');
});

it('returns the value of the action_input property when assistantLangChain is true, and `content` has properly prefixed and suffixed JSON with the action_input property', async () => {
const content = '```json\n{"action_input": "value from action_input"}\n```';

(mockHttp.fetch as jest.Mock).mockResolvedValue({
status: 'ok',
data: {
choices: [
{
message: {
content,
},
},
],
},
data: content,
});

const testProps: FetchConnectorExecuteAction = {
Expand All @@ -160,15 +126,7 @@ describe('fetchConnectorExecuteAction', () => {

(mockHttp.fetch as jest.Mock).mockResolvedValue({
status: 'ok',
data: {
choices: [
{
message: {
content,
},
},
],
},
data: content,
});

const testProps: FetchConnectorExecuteAction = {
Expand All @@ -188,15 +146,7 @@ describe('fetchConnectorExecuteAction', () => {

(mockHttp.fetch as jest.Mock).mockResolvedValue({
status: 'ok',
data: {
choices: [
{
message: {
content,
},
},
],
},
data: content,
});

const testProps: FetchConnectorExecuteAction = {
Expand Down
41 changes: 17 additions & 24 deletions x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,14 @@ export const fetchConnectorExecuteAction = async ({
temperature: 0.2,
}
: {
// Azure OpenAI and Bedrock invokeAI both expect this body format
messages: outboundMessages,
};

const requestBody = {
params: {
subActionParams: {
body: JSON.stringify(body),
},
subAction: 'test',
subActionParams: body,
subAction: 'invokeAI',
},
};

Expand All @@ -61,29 +60,23 @@ export const fetchConnectorExecuteAction = async ({
? `/internal/elastic_assistant/actions/connector/${apiConfig?.connectorId}/_execute`
: `/api/actions/connector/${apiConfig?.connectorId}/_execute`;

// TODO: Find return type for this API
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const response = await http.fetch<any>(path, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
signal,
});

const data = response.data;
if (response.status !== 'ok') {
const response = await http.fetch<{ connector_id: string; status: string; data: string }>(
path,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
signal,
}
);

if (response.status !== 'ok' || !response.data) {
return API_ERROR;
}

if (data.choices && data.choices.length > 0 && data.choices[0].message.content) {
const result = data.choices[0].message.content.trim();

return assistantLangChain ? getFormattedMessageContent(result) : result;
} else {
return API_ERROR;
}
return assistantLangChain ? getFormattedMessageContent(response.data) : response.data;
} catch (error) {
return API_ERROR;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ export const AssistantTitle: React.FC<{
<EuiFlexItem grow={false}>
<ConnectorSelectorInline
isDisabled={isDisabled || selectedConversation === undefined}
onConnectorModalVisibilityChange={() => {}}
selectedConnectorId={selectedConnectorId}
selectedConversation={selectedConversation}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import { EuiFormRow, EuiLink, EuiTitle, EuiText, EuiHorizontalRule, EuiSpacer } from '@elastic/eui';
import React, { useCallback, useMemo } from 'react';

import { ActionTypeRegistryContract } from '@kbn/triggers-actions-ui-plugin/public';
import { HttpSetup } from '@kbn/core-http-browser';
import { FormattedMessage } from '@kbn/i18n-react';
import { OpenAiProviderType } from '@kbn/stack-connectors-plugin/public/common';
Expand All @@ -27,7 +26,6 @@ import { useLoadConnectors } from '../../../connectorland/use_load_connectors';
import { getGenAiConfig } from '../../../connectorland/helpers';

export interface ConversationSettingsProps {
actionTypeRegistry: ActionTypeRegistryContract;
allSystemPrompts: Prompt[];
conversationSettings: UseAssistantContext['conversations'];
defaultConnectorId?: string;
Expand All @@ -46,7 +44,6 @@ export interface ConversationSettingsProps {
*/
export const ConversationSettings: React.FC<ConversationSettingsProps> = React.memo(
({
actionTypeRegistry,
allSystemPrompts,
defaultConnectorId,
defaultProvider,
Expand Down Expand Up @@ -250,10 +247,7 @@ export const ConversationSettings: React.FC<ConversationSettingsProps> = React.m
}
>
<ConnectorSelector
actionTypeRegistry={actionTypeRegistry}
http={http}
isDisabled={selectedConversation == null}
onConnectorModalVisibilityChange={() => {}}
onConnectorSelectionChange={handleOnConnectorSelectionChange}
selectedConnectorId={selectedConnector?.id}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,8 @@ export const AssistantSettings: React.FC<Props> = React.memo(
selectedConversation: defaultSelectedConversation,
setSelectedConversationId,
}) => {
const {
actionTypeRegistry,
assistantLangChain,
http,
selectedSettingsTab,
setSelectedSettingsTab,
} = useAssistantContext();
const { assistantLangChain, http, selectedSettingsTab, setSelectedSettingsTab } =
useAssistantContext();
const {
conversationSettings,
defaultAllow,
Expand Down Expand Up @@ -267,7 +262,6 @@ export const AssistantSettings: React.FC<Props> = React.memo(
conversationSettings={conversationSettings}
setUpdatedConversationSettings={setUpdatedConversationSettings}
allSystemPrompts={systemPromptSettings}
actionTypeRegistry={actionTypeRegistry}
selectedConversation={selectedConversation}
onSelectedConversationChange={onHandleSelectedConversationChange}
http={http}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface ConversationTheme {
export interface Conversation {
apiConfig: {
connectorId?: string;
connectorTypeTitle?: string;
defaultSystemPromptId?: string;
provider?: OpenAiProviderType;
model?: string;
Expand Down
Loading
Loading