mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
Unauthorized route migration for routes owned by kibana-data-discovery (#198332)
### Authz API migration for unauthorized routes This PR migrates unauthorized routes owned by your team to a new security configuration. Please refer to the documentation for more information: [Authorization API](https://docs.elastic.dev/kibana-dev-docs/key-concepts/security-api-authorization) ### **Before migration:** ```ts router.get({ path: '/api/path', ... }, handler); ``` ### **After migration:** ```ts router.get({ path: '/api/path', security: { authz: { enabled: false, reason: 'This route is opted out from authorization because ...', }, }, ... }, handler); ``` ### What to do next? 1. Review the changes in this PR. 2. Elaborate on the reasoning to opt-out of authorization. 3. Routes without a compelling reason to opt-out of authorization should plan to introduce them as soon as possible. 2. You might need to update your tests to reflect the new security configuration: - If you have snapshot tests that include the route definition. ## Any questions? If you have any questions or need help with API authorization, please reach out to the `@elastic/kibana-security` team. --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Lukas Olson <lukas@elastic.co> Co-authored-by: Davis McPhee <davis.mcphee@elastic.co> Co-authored-by: Matthias Wilhelm <matthias.wilhelm@elastic.co>
This commit is contained in:
parent
5ed54ec93c
commit
fc8ca4f3b8
29 changed files with 191 additions and 15 deletions
|
@ -51,6 +51,12 @@ export const registerFieldPreviewRoute = ({ router }: RouteDependencies): void =
|
|||
router.versioned.post({ path, access: 'internal' }).addVersion(
|
||||
{
|
||||
version: '1',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by Elasticsearch',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
body: bodySchema,
|
||||
|
|
|
@ -14,6 +14,12 @@ export function registerPreviewScriptedFieldRoute(router: IRouter): void {
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/index-pattern-management/preview_scripted_field',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by Elasticsearch',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
index: schema.string(),
|
||||
|
|
|
@ -15,6 +15,12 @@ export function registerResolveIndexRoute(router: IRouter): void {
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/index-pattern-management/resolve_index/{query}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by Elasticsearch',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({
|
||||
query: schema.string(),
|
||||
|
|
|
@ -60,6 +60,12 @@ export const registerExistingIndicesPath = (router: IRouter): void => {
|
|||
.addVersion(
|
||||
{
|
||||
version,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route is opted out from authorization',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
query: schema.object({
|
||||
|
|
|
@ -146,10 +146,17 @@ export const registerFields = (
|
|||
>,
|
||||
isRollupsEnabled: () => boolean
|
||||
) => {
|
||||
router.versioned
|
||||
.get({ path, access: 'internal', enableQueryVersion: true })
|
||||
.addVersion(
|
||||
{ version: '1', validate: { request: { query: querySchema }, response: validate.response } },
|
||||
handler(isRollupsEnabled)
|
||||
);
|
||||
router.versioned.get({ path, access: 'internal', enableQueryVersion: true }).addVersion(
|
||||
{
|
||||
version: '1',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by Elasticsearch',
|
||||
},
|
||||
},
|
||||
validate: { request: { query: querySchema }, response: validate.response },
|
||||
},
|
||||
handler(isRollupsEnabled)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import { estypes } from '@elastic/elasticsearch';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter, RequestHandler, StartServicesAccessor } from '@kbn/core/server';
|
||||
import type { IRouter, RequestHandler, RouteAuthz, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { VersionedRouteValidation } from '@kbn/core-http-server';
|
||||
import { INITIAL_REST_VERSION_INTERNAL as version } from '../../constants';
|
||||
import { IndexPatternsFetcher } from '../../fetcher';
|
||||
|
@ -217,14 +217,31 @@ export const registerFieldForWildcard = (
|
|||
isRollupsEnabled: () => boolean
|
||||
) => {
|
||||
const configuredHandler = handler(isRollupsEnabled);
|
||||
const authz: RouteAuthz = { enabled: false, reason: 'Authorization provided by Elasticsearch' };
|
||||
|
||||
// handler
|
||||
router.versioned.put({ path, access }).addVersion({ version, validate }, configuredHandler);
|
||||
router.versioned.post({ path, access }).addVersion({ version, validate }, configuredHandler);
|
||||
router.versioned
|
||||
.get({ path, access })
|
||||
.addVersion(
|
||||
{ version, validate: { request: { query: querySchema }, response: validate.response } },
|
||||
configuredHandler
|
||||
);
|
||||
router.versioned.put({ path, access }).addVersion(
|
||||
{
|
||||
version,
|
||||
security: { authz },
|
||||
validate,
|
||||
},
|
||||
configuredHandler
|
||||
);
|
||||
router.versioned.post({ path, access }).addVersion(
|
||||
{
|
||||
version,
|
||||
security: { authz },
|
||||
validate,
|
||||
},
|
||||
configuredHandler
|
||||
);
|
||||
router.versioned.get({ path, access }).addVersion(
|
||||
{
|
||||
version,
|
||||
security: { authz },
|
||||
validate: { request: { query: querySchema }, response: validate.response },
|
||||
},
|
||||
configuredHandler
|
||||
);
|
||||
};
|
||||
|
|
|
@ -45,6 +45,12 @@ export const registerHasDataViewsRoute = (router: IRouter): void => {
|
|||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
response: {
|
||||
200: {
|
||||
|
|
|
@ -133,6 +133,12 @@ export const registerHasEsDataRoute = (
|
|||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by Elasticsearch',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
response: {
|
||||
200: {
|
||||
|
|
|
@ -61,6 +61,11 @@ const registerCreateDataViewRouteFactory =
|
|||
router.versioned.post({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
body: schema.object({
|
||||
|
|
|
@ -73,6 +73,12 @@ const manageDefaultIndexPatternRoutesFactory =
|
|||
router.versioned.get({ path, access: 'public', description: getDescription }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
|
@ -110,6 +116,11 @@ const manageDefaultIndexPatternRoutesFactory =
|
|||
router.versioned.post({ path, access: 'public', description: postDescription }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
body: schema.object({
|
||||
|
|
|
@ -53,6 +53,11 @@ const deleteIndexPatternRouteFactory =
|
|||
router.versioned.delete({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -131,6 +131,11 @@ const updateFieldsActionRouteFactory = (path: string, serviceKey: string, descri
|
|||
router.versioned.post({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -57,6 +57,12 @@ const getDataViewRouteFactory =
|
|||
router.versioned.get({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -66,6 +66,12 @@ const getDataViewsRouteFactory =
|
|||
router.versioned.get({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {},
|
||||
response: { 200: { body: responseValidation } },
|
||||
|
|
|
@ -46,6 +46,12 @@ const hasUserDataViewRouteFactory =
|
|||
router.versioned.get({ path, access: 'internal' }).addVersion(
|
||||
{
|
||||
version: '1',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
|
|
|
@ -82,6 +82,11 @@ const runtimeCreateFieldRouteFactory =
|
|||
router.versioned.post({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -65,6 +65,11 @@ const deleteRuntimeFieldRouteFactory =
|
|||
router.versioned.delete({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -73,6 +73,12 @@ const getRuntimeFieldRouteFactory =
|
|||
router.versioned.get({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -81,6 +81,11 @@ const putRuntimeFieldRouteFactory =
|
|||
router.versioned.put({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -81,6 +81,11 @@ const updateRuntimeFieldRouteFactory =
|
|||
router.versioned.post({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -31,6 +31,11 @@ export const registerCreateScriptedFieldRoute = (
|
|||
.addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -32,6 +32,11 @@ export const registerDeleteScriptedFieldRoute = (
|
|||
.addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -31,6 +31,12 @@ export const registerGetScriptedFieldRoute = (
|
|||
.addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -31,6 +31,11 @@ export const registerPutScriptedFieldRoute = (
|
|||
.addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -36,6 +36,11 @@ export const registerUpdateScriptedFieldRoute = (
|
|||
.addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -70,6 +70,14 @@ export const swapReferencesRoute =
|
|||
router.versioned.post({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
// We don't use the indexPatterns:manage privilege for this route because it can be used for saved object
|
||||
// types other than index-pattern
|
||||
reason: 'Authorization provided by saved objects client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
body: schema.object({
|
||||
|
|
|
@ -147,6 +147,11 @@ const updateDataViewRouteFactory =
|
|||
router.versioned.post({ path, access: 'public', description }).addVersion(
|
||||
{
|
||||
version: INITIAL_REST_VERSION,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['indexPatterns:manage'],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object(
|
||||
|
|
|
@ -881,6 +881,9 @@ exports[`buildOSSFeatures with a basic license returns the indexPatterns feature
|
|||
Array [
|
||||
Object {
|
||||
"privilege": Object {
|
||||
"api": Array [
|
||||
"indexPatterns:manage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
],
|
||||
|
@ -1520,6 +1523,9 @@ exports[`buildOSSFeatures with a enterprise license returns the indexPatterns fe
|
|||
Array [
|
||||
Object {
|
||||
"privilege": Object {
|
||||
"api": Array [
|
||||
"indexPatterns:manage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
],
|
||||
|
|
|
@ -401,6 +401,7 @@ export const buildOSSFeatures = ({
|
|||
read: [],
|
||||
},
|
||||
ui: ['save'],
|
||||
api: ['indexPatterns:manage'],
|
||||
},
|
||||
read: {
|
||||
app: ['kibana'],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue