Skip to content
Merged
Show file tree
Hide file tree
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
80 changes: 79 additions & 1 deletion x-pack/test/security_solution_cypress/cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,86 @@ Per the way we set the environment during the execution process on CI, the above

For test developing or test debugging purposes, you need to modify the configuration but without committing and pushing the changes in `x-pack/test/security_solution_cypress/serverless_config.ts`.

#### Custom Roles

### Running serverless tests locally pointing to a MKI project created in QA environment (Kibana QA quality gate)
Custom roles for serverless is currently supported only for stateless environments (non MKI environments).

##### Creating a Custom Role

To create a custom role, use the Cypress task `createServerlessCustomRole`. This task requires two parameters:
- **`roleDescriptor`**: Defines the permissions and access for the role.
- **`roleName`**: A unique name for the custom role.

Example:

```typescript
const roleDescriptor = {
elasticsearch: {
cluster: ['monitor'],
indices: [{ names: ['*'], privileges: ['read'] }],
},
kibana: [
{
base: ['all'],
feature: {},
spaces: ['*'],
},
],
};

cy.task('createServerlessCustomRole', { roleDescriptor, roleName: 'customRole' });
```

##### Using a Custom Role

Once the custom role is created, you can log in to the application using your regular `login`` method and passing the name of the role.

```typescript
login('customRole');
```


##### Deleting a Custom Role

After your tests, always delete the custom role to ensure a clean environment. Use the `deleteServerlessCustomRole` task and provide the name of the role as the parameter.

```typescript
cy.task('deleteServerlessCustomRole', 'customRole');
```

##### Full workflow

Here’s the complete workflow for creating, using, and deleting a custom role:

```typescript
const roleDescriptor = {
elasticsearch: {
cluster: ['monitor'],
indices: [{ names: ['*'], privileges: ['read'] }],
},
kibana: [
{
base: ['all'],
feature: {},
spaces: ['*'],
},
],
};

before(() => {
cy.task('createServerlessCustomRole', { roleDescriptor, roleName: 'customRole' });
});

beforeEach(() => {
login('customRole');
});

after(() => {
cy.task('deleteServerlessCustomRole', 'customRole');
});
```

### Running serverless tests locally pointing to a MKI project created in QA environment

Note that when using any of the below scripts, the tests are going to be executed through an MKI project with the version that is currently available in QA. If you need to use
a specific commit (i.e. debugging a failing tests on the periodic pipeline), check the section: `Running serverless tests locally pointing to a MKI project created in QA environment with an overridden image`.
Expand Down
48 changes: 46 additions & 2 deletions x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import type { Role } from '@kbn/security-plugin-types-common';

import { ToolingLog } from '@kbn/tooling-log';

import { SecurityRoleName } from '@kbn/security-solution-plugin/common/test';
Expand Down Expand Up @@ -67,13 +69,13 @@ export const samlAuthentication = async (
cloudUsersFilePath,
});

const adminCookieHeader = await sessionManager.getApiCredentialsForRole('admin');

on('task', {
getSessionCookie: async (role: string | SecurityRoleName): Promise<string> => {
return sessionManager.getInteractiveUserSessionCookieWithRoleScope(role);
},
getApiKeyForRole: async (role: string | SecurityRoleName): Promise<string> => {
const adminCookieHeader = await sessionManager.getApiCredentialsForRole('admin');

let roleDescriptor = {};

const roleConfig = getRoleConfiguration(role, rolesPath);
Expand All @@ -98,6 +100,48 @@ export const samlAuthentication = async (
const apiKey = response.data.encoded;
return apiKey;
},
createServerlessCustomRole: async ({
roleDescriptor,
roleName,
}: {
roleDescriptor: { kibana: Role['kibana']; elasticsearch: Role['elasticsearch'] };
roleName: string;
}): Promise<{ status: number; data: Role }> => {
const customRoleDescriptors = {
kibana: roleDescriptor.kibana,
elasticsearch: roleDescriptor.elasticsearch ?? [],
};

const response = await axios.put(
`${kbnHost}/api/security/role/${roleName}`,
customRoleDescriptors,
{
headers: {
...INTERNAL_REQUEST_HEADERS,
...adminCookieHeader,
},
}
);
return {
status: response.status,
data: response.data,
};
},
deleteServerlessCustomRole: async (
roleName: string
): Promise<{ status: number; data: unknown }> => {
const response = await axios.delete(`${kbnHost}/api/security/role/${roleName}`, {
headers: {
...INTERNAL_REQUEST_HEADERS,
...adminCookieHeader,
},
});

return {
status: response.status,
data: response.data,
};
},
getFullname: async (
role: string | SecurityRoleName = DEFAULT_SERVERLESS_ROLE
): Promise<string> => {
Expand Down
5 changes: 2 additions & 3 deletions x-pack/test/security_solution_cypress/cypress/tasks/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/
import { LoginState } from '@kbn/security-plugin/common/login_state';
import type { SecurityRoleName } from '@kbn/security-solution-plugin/common/test';
import { KNOWN_SERVERLESS_ROLE_DEFINITIONS } from '@kbn/security-solution-plugin/common/test';
import { LOGOUT_URL } from '../urls/navigation';
import {
Expand All @@ -27,7 +26,7 @@ export const defaultUser: User = {
password: Cypress.env(ELASTICSEARCH_PASSWORD),
};

export const getEnvAuth = (role: SecurityRoleName): User => {
export const getEnvAuth = (role: string): User => {
if (
(Cypress.env(IS_SERVERLESS) || Cypress.env(CLOUD_SERVERLESS)) &&
!(role in KNOWN_SERVERLESS_ROLE_DEFINITIONS)
Expand All @@ -41,7 +40,7 @@ export const getEnvAuth = (role: SecurityRoleName): User => {
return user;
};

export const login = (role?: SecurityRoleName): void => {
export const login = (role?: string): void => {
let testRole = '';

if (Cypress.env(IS_SERVERLESS)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@
"@kbn/repo-info",
"@kbn/elastic-assistant-common",
"@kbn/cloud-security-posture-common",
"@kbn/security-plugin-types-common",
]
}