Skip to content

Commit 9522dd2

Browse files
Merge branch 'main' into ab_security_opt_in
2 parents e99e967 + 7b30d06 commit 9522dd2

File tree

244 files changed

+15746
-1784
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

244 files changed

+15746
-1784
lines changed

.buildkite/ftr_platform_stateful_configs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ enabled:
338338
- x-pack/platform/test/spaces_api_integration/security_and_spaces/config_basic.ts
339339
- x-pack/platform/test/spaces_api_integration/security_and_spaces/config_trial.ts
340340
- x-pack/platform/test/spaces_api_integration/spaces_only/config.ts
341+
- x-pack/platform/test/spaces_api_integration/access_control_objects/config.ts
342+
- x-pack/platform/test/spaces_api_integration/access_control_objects/feature_disabled.config.ts
341343
- x-pack/platform/test/task_manager_claimer_update_by_query/config.ts
342344
- x-pack/platform/test/ui_capabilities/security_and_spaces/config.ts
343345
- x-pack/platform/test/ui_capabilities/spaces_only/config.ts

.buildkite/pipelines/on_merge_unsupported_ftrs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ steps:
3838
preemptible: true
3939
depends_on: build
4040
env:
41-
PING_SLACK_TEAM: "@obs-ux-management-team"
41+
PING_SLACK_TEAM: '@actionable-obs-team'
4242
timeout_in_minutes: 120
4343
artifact_paths:
4444
- 'x-pack/solutions/observability/plugins/synthetics/e2e/.journeys/**/*'

.github/CODEOWNERS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,8 @@ src/platform/packages/private/shared-ux/storybook/config @elastic/appex-sharedux
403403
src/platform/packages/shared/chart-expressions-common @elastic/kibana-visualizations
404404
src/platform/packages/shared/chart-test-jest-helpers @elastic/kibana-visualizations
405405
src/platform/packages/shared/cloud @elastic/kibana-core
406+
src/platform/packages/shared/content-management/access_control/access_control_public @elastic/appex-sharedux
407+
src/platform/packages/shared/content-management/access_control/access_control_server @elastic/appex-sharedux
406408
src/platform/packages/shared/content-management/content_editor @elastic/appex-sharedux
407409
src/platform/packages/shared/content-management/content_insights/content_insights_public @elastic/appex-sharedux
408410
src/platform/packages/shared/content-management/content_insights/content_insights_server @elastic/appex-sharedux
@@ -1125,6 +1127,7 @@ x-pack/platform/test/security_api_integration/plugins/oidc_provider @elastic/kib
11251127
x-pack/platform/test/security_api_integration/plugins/saml_provider @elastic/kibana-security
11261128
x-pack/platform/test/security_api_integration/plugins/user_profiles_consumer @elastic/kibana-security
11271129
x-pack/platform/test/security_functional/plugins/test_endpoints @elastic/kibana-security
1130+
x-pack/platform/test/spaces_api_integration/common/plugins/access_control_test_plugin @elastic/kibana-security
11281131
x-pack/platform/test/spaces_api_integration/common/plugins/spaces_test_plugin @elastic/kibana-security
11291132
x-pack/platform/test/task_manager_claimer_update_by_query/plugins/sample_task_plugin_mget @elastic/response-ops
11301133
x-pack/platform/test/ui_capabilities/common/plugins/foo_plugin @elastic/kibana-security
@@ -2307,6 +2310,8 @@ x-pack/platform/plugins/private/cloud_integrations/cloud_full_story/server/confi
23072310
/x-pack/solutions/**/test/serverless/**/test_suites/rules/ @elastic/response-ops
23082311

23092312
# Connector Specs
2313+
src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts @kibanamachine
2314+
src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts @kibanamachine
23102315
src/platform/packages/shared/kbn-connector-specs/src/specs/** @elastic/workflows-eng
23112316

23122317
# Gap fill feature has shared responsibility between response-ops and security-detection-engine

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@
166166
"@hapi/wreck": "^18.1.0",
167167
"@hello-pangea/dnd": "18.0.1",
168168
"@kbn/aad-fixtures-plugin": "link:x-pack/platform/test/alerting_api_integration/common/plugins/aad",
169+
"@kbn/access-control-test-plugin": "link:x-pack/platform/test/spaces_api_integration/common/plugins/access_control_test_plugin",
169170
"@kbn/actions-plugin": "link:x-pack/platform/plugins/shared/actions",
170171
"@kbn/actions-simulators-plugin": "link:x-pack/platform/test/alerting_api_integration/common/plugins/actions_simulators",
171172
"@kbn/actions-types": "link:src/platform/packages/shared/kbn-actions-types",
@@ -261,6 +262,8 @@
261262
"@kbn/connector-specs": "link:src/platform/packages/shared/kbn-connector-specs",
262263
"@kbn/console-plugin": "link:src/platform/plugins/shared/console",
263264
"@kbn/content-connectors-plugin": "link:x-pack/platform/plugins/shared/content_connectors",
265+
"@kbn/content-management-access-control-public": "link:src/platform/packages/shared/content-management/access_control/access_control_public",
266+
"@kbn/content-management-access-control-server": "link:src/platform/packages/shared/content-management/access_control/access_control_server",
264267
"@kbn/content-management-content-editor": "link:src/platform/packages/shared/content-management/content_editor",
265268
"@kbn/content-management-content-insights-public": "link:src/platform/packages/shared/content-management/content_insights/content_insights_public",
266269
"@kbn/content-management-content-insights-server": "link:src/platform/packages/shared/content-management/content_insights/content_insights_server",

src/core/packages/plugins/server-internal/src/plugin_context.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,10 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>({
266266
setEncryptionExtension: deps.savedObjects.setEncryptionExtension,
267267
setSecurityExtension: deps.savedObjects.setSecurityExtension,
268268
setSpacesExtension: deps.savedObjects.setSpacesExtension,
269+
setAccessControlTransforms: deps.savedObjects.setAccessControlTransforms,
269270
registerType: deps.savedObjects.registerType,
270271
getDefaultIndex: deps.savedObjects.getDefaultIndex,
272+
isAccessControlEnabled: deps.savedObjects.isAccessControlEnabled,
271273
},
272274
status: {
273275
core$: deps.status.core$,

src/core/packages/saved-objects/api-server-internal/src/lib/apis/bulk_create.test.ts

Lines changed: 265 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ import {
1919

2020
import type { Payload } from '@hapi/boom';
2121

22-
import type { SavedObjectsBulkCreateObject } from '@kbn/core-saved-objects-api-server';
22+
import type {
23+
SavedObjectAccessControl,
24+
SavedObjectsBulkCreateObject,
25+
} from '@kbn/core-saved-objects-api-server';
2326
import {
2427
type SavedObjectsRawDoc,
2528
type SavedObjectUnsanitizedDoc,
@@ -58,6 +61,7 @@ import {
5861
} from '../../test_helpers/repository.test.common';
5962
import type { ISavedObjectsSecurityExtension } from '@kbn/core-saved-objects-server';
6063
import { savedObjectsExtensionsMock } from '../../mocks/saved_objects_extensions.mock';
64+
import type { AuthenticatedUser } from '@kbn/core-security-common';
6165

6266
// so any breaking changes to this repository are considered breaking changes to the SavedObjectsClient.
6367

@@ -1086,6 +1090,266 @@ describe('#bulkCreate', () => {
10861090
})
10871091
);
10881092
});
1093+
1094+
describe('access control', () => {
1095+
const CURRENT_USER_PROFILE_ID = 'current_user_profile_id';
1096+
const ACCESS_CONTROL_TYPE = 'access-control-type';
1097+
1098+
beforeEach(() => {
1099+
securityExtension.getCurrentUser.mockReturnValue({
1100+
authentication_realm: {
1101+
name: 'authentication_realm',
1102+
type: 'authentication_realm_type',
1103+
},
1104+
lookup_realm: {
1105+
name: 'lookup_realm',
1106+
type: 'lookup_realm_type',
1107+
},
1108+
authentication_provider: {
1109+
name: 'authentication_provider',
1110+
type: 'authentication_provider_type',
1111+
},
1112+
authentication_type: 'realm',
1113+
elastic_cloud_user: false,
1114+
profile_uid: CURRENT_USER_PROFILE_ID,
1115+
} as AuthenticatedUser);
1116+
});
1117+
1118+
registry.registerType({
1119+
name: ACCESS_CONTROL_TYPE,
1120+
hidden: false,
1121+
namespaceType: 'multiple-isolated',
1122+
supportsAccessControl: true,
1123+
mappings: {
1124+
dynamic: false,
1125+
properties: {
1126+
description: { type: 'text' },
1127+
},
1128+
},
1129+
management: {
1130+
importableAndExportable: true,
1131+
},
1132+
});
1133+
1134+
afterEach(() => {
1135+
securityExtension.getCurrentUser.mockClear();
1136+
});
1137+
1138+
it('applies access control options only to applicable types when using global access control options', async () => {
1139+
const obj1NoAccessControl = {
1140+
type: 'config',
1141+
id: '6.0.0-alpha1',
1142+
attributes: { title: 'Test One' },
1143+
references: [{ name: 'ref_0', type: 'test', id: '1' }],
1144+
};
1145+
const obj2AccessControl = {
1146+
type: ACCESS_CONTROL_TYPE,
1147+
id: 'has-read-only-metadata',
1148+
attributes: { title: 'Test Two' },
1149+
references: [{ name: 'ref_0', type: 'test', id: '2' }],
1150+
};
1151+
await bulkCreateSuccess(client, repository, [obj1NoAccessControl, obj2AccessControl], {
1152+
accessControl: { accessMode: 'write_restricted' },
1153+
});
1154+
1155+
expect(securityExtension.authorizeBulkCreate).toHaveBeenCalledWith(
1156+
expect.objectContaining({
1157+
objects: expect.arrayContaining([
1158+
{
1159+
type: ACCESS_CONTROL_TYPE,
1160+
id: 'has-read-only-metadata',
1161+
name: 'Test Two',
1162+
existingNamespaces: [],
1163+
initialNamespace: undefined,
1164+
accessControl: {
1165+
owner: CURRENT_USER_PROFILE_ID,
1166+
accessMode: 'write_restricted',
1167+
},
1168+
},
1169+
]),
1170+
})
1171+
);
1172+
});
1173+
1174+
it('applies access control options to supporting types when using per object access control options', async () => {
1175+
const obj1NoAccessControl = {
1176+
type: 'config',
1177+
id: '6.0.0-alpha1',
1178+
attributes: { title: 'Test One' },
1179+
references: [{ name: 'ref_0', type: 'test', id: '1' }],
1180+
};
1181+
const obj2AccessControl = {
1182+
type: ACCESS_CONTROL_TYPE,
1183+
id: 'has-read-only-metadata',
1184+
attributes: { title: 'Test Two' },
1185+
references: [{ name: 'ref_0', type: 'test', id: '2' }],
1186+
accessControl: {
1187+
accessMode: 'write_restricted',
1188+
} as Pick<SavedObjectAccessControl, 'accessMode'>,
1189+
};
1190+
await bulkCreateSuccess(client, repository, [obj1NoAccessControl, obj2AccessControl]);
1191+
1192+
expect(securityExtension.authorizeBulkCreate).toHaveBeenCalledWith({
1193+
objects: [
1194+
{
1195+
type: 'config',
1196+
id: '6.0.0-alpha1',
1197+
name: 'Test One',
1198+
existingNamespaces: [],
1199+
initialNamespaces: undefined,
1200+
},
1201+
{
1202+
type: ACCESS_CONTROL_TYPE,
1203+
id: 'has-read-only-metadata',
1204+
name: 'Test Two',
1205+
existingNamespaces: [],
1206+
initialNamespaces: undefined,
1207+
accessControl: {
1208+
owner: CURRENT_USER_PROFILE_ID,
1209+
accessMode: 'write_restricted',
1210+
},
1211+
},
1212+
],
1213+
});
1214+
});
1215+
1216+
it('overrides access control options with incoming object property only for applicable types', async () => {
1217+
const obj1NoAccessControl = {
1218+
type: 'config',
1219+
id: '6.0.0-alpha1',
1220+
attributes: { title: 'Test One' },
1221+
references: [{ name: 'ref_0', type: 'test', id: '1' }],
1222+
accessControl: {
1223+
accessMode: 'write_restricted',
1224+
} as Pick<SavedObjectAccessControl, 'accessMode'>,
1225+
};
1226+
const obj2AccessControl = {
1227+
type: ACCESS_CONTROL_TYPE,
1228+
id: 'has-read-only-metadata',
1229+
attributes: { title: 'Test Two' },
1230+
references: [{ name: 'ref_0', type: 'test', id: '2' }],
1231+
accessControl: {
1232+
accessMode: 'default', // default === RBAC-only
1233+
} as Pick<SavedObjectAccessControl, 'accessMode'>,
1234+
};
1235+
const obj3AccessControl = {
1236+
type: ACCESS_CONTROL_TYPE,
1237+
id: 'has-read-only-metadata',
1238+
attributes: { title: 'Test Three' },
1239+
references: [{ name: 'ref_0', type: 'test', id: '3' }],
1240+
};
1241+
const obj4NoAccessControl = {
1242+
type: 'config',
1243+
id: '6.0.0-alpha4',
1244+
attributes: { title: 'Test One' },
1245+
references: [{ name: 'ref_0', type: 'test', id: '1' }],
1246+
};
1247+
1248+
await bulkCreateSuccess(
1249+
client,
1250+
repository,
1251+
[obj1NoAccessControl, obj2AccessControl, obj3AccessControl, obj4NoAccessControl],
1252+
{
1253+
accessControl: { accessMode: 'write_restricted' },
1254+
}
1255+
);
1256+
1257+
expect(securityExtension.authorizeBulkCreate).toHaveBeenCalledWith({
1258+
objects: [
1259+
{
1260+
type: ACCESS_CONTROL_TYPE,
1261+
id: 'has-read-only-metadata',
1262+
name: 'Test Two',
1263+
existingNamespaces: [],
1264+
initialNamespace: undefined,
1265+
accessControl: {
1266+
owner: CURRENT_USER_PROFILE_ID,
1267+
accessMode: 'default', // explicitly confirm the mode is overriden
1268+
},
1269+
},
1270+
{
1271+
type: ACCESS_CONTROL_TYPE,
1272+
id: 'has-read-only-metadata',
1273+
name: 'Test Three',
1274+
existingNamespaces: [],
1275+
initialNamespace: undefined,
1276+
accessControl: {
1277+
owner: CURRENT_USER_PROFILE_ID,
1278+
accessMode: 'write_restricted', // explicitly confirm the mode is NOT overriden
1279+
},
1280+
},
1281+
],
1282+
});
1283+
});
1284+
1285+
it('does not create objects with access control when there is no active user profile', async () => {
1286+
securityExtension.getCurrentUser.mockReturnValueOnce(null);
1287+
1288+
const obj1NoAccessControl = {
1289+
type: 'config',
1290+
id: '6.0.0-alpha1',
1291+
attributes: { title: 'Test One' },
1292+
references: [{ name: 'ref_0', type: 'test', id: '1' }],
1293+
accessControl: {
1294+
accessMode: 'write_restricted',
1295+
} as Pick<SavedObjectAccessControl, 'accessMode'>,
1296+
};
1297+
const obj2AccessControl = {
1298+
type: ACCESS_CONTROL_TYPE,
1299+
id: 'has-read-only-metadata',
1300+
attributes: { title: 'Test Two' },
1301+
references: [{ name: 'ref_0', type: 'test', id: '2' }],
1302+
accessControl: {
1303+
accessMode: 'write_restricted',
1304+
} as Pick<SavedObjectAccessControl, 'accessMode'>,
1305+
};
1306+
await bulkCreateSuccess(client, repository, [obj1NoAccessControl, obj2AccessControl]);
1307+
1308+
expect(securityExtension.authorizeBulkCreate).not.toHaveBeenCalled();
1309+
});
1310+
1311+
// regression test
1312+
it('creates objects supporting access control with no access control metadata when there is no active user profile and no access mode is provided', async () => {
1313+
securityExtension.getCurrentUser.mockReturnValueOnce(null);
1314+
1315+
const obj1NoAccessControl = {
1316+
type: 'config',
1317+
id: '6.0.0-alpha1',
1318+
attributes: { title: 'Test One' },
1319+
references: [{ name: 'ref_0', type: 'test', id: '1' }],
1320+
};
1321+
const obj2AccessControl = {
1322+
type: ACCESS_CONTROL_TYPE,
1323+
id: 'could-have-read-only-metadata',
1324+
attributes: { title: 'Test Two' },
1325+
references: [{ name: 'ref_0', type: 'test', id: '2' }],
1326+
};
1327+
await bulkCreateSuccess(client, repository, [obj1NoAccessControl, obj2AccessControl]); // no accessControl options
1328+
1329+
expect(securityExtension.authorizeBulkCreate).toHaveBeenCalledWith(
1330+
expect.objectContaining({
1331+
objects: [
1332+
{
1333+
type: 'config',
1334+
id: '6.0.0-alpha1',
1335+
name: 'Test One',
1336+
existingNamespaces: [],
1337+
initialNamespace: undefined,
1338+
// explicitly confirm there is no accessControl for non-supporting type
1339+
},
1340+
{
1341+
type: ACCESS_CONTROL_TYPE,
1342+
id: 'could-have-read-only-metadata',
1343+
name: 'Test Two',
1344+
existingNamespaces: [],
1345+
initialNamespace: undefined,
1346+
// explicitly confirm there is no accessControl for supporting type
1347+
},
1348+
],
1349+
})
1350+
);
1351+
});
1352+
});
10891353
});
10901354
});
10911355
});

0 commit comments

Comments
 (0)