mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Unauthorized route migration for routes owned by kibana-security (#198334)
### 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: “jeramysoucy” <jeramy.soucy@elastic.co> Co-authored-by: Larry Gregory <larry.gregory@elastic.co> Co-authored-by: Elena Shostak <165678770+elena-shostak@users.noreply.github.com> Co-authored-by: Elena Shostak <elena.shostak@elastic.co>
This commit is contained in:
parent
0df2e98381
commit
c994b48805
58 changed files with 483 additions and 16 deletions
|
@ -37,6 +37,13 @@ export function defineConfigureRoute({
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/interactive_setup/configure',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
host: schema.uri({ scheme: ['http', 'https'] }),
|
||||
|
|
|
@ -40,6 +40,13 @@ export function defineEnrollRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/interactive_setup/enroll',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
hosts: schema.arrayOf(schema.uri({ scheme: 'https' }), {
|
||||
|
|
|
@ -17,6 +17,13 @@ export function definePingRoute({ router, logger, elasticsearch, preboot }: Rout
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/interactive_setup/ping',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
host: schema.uri({ scheme: ['http', 'https'] }),
|
||||
|
|
|
@ -15,6 +15,13 @@ export function defineStatusRoute({ router, elasticsearch, preboot }: RouteDefin
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/interactive_setup/status',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
options: { authRequired: false },
|
||||
},
|
||||
|
|
|
@ -15,6 +15,13 @@ export function defineVerifyRoute({ router, verificationCode }: RouteDefinitionP
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/interactive_setup/verify',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
code: schema.string(),
|
||||
|
|
|
@ -31,6 +31,13 @@ export function defineRecordAnalyticsOnAuthTypeRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/analytics/_record_auth_type',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the scoped ES cluster client of the internal authentication service',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.nullable(
|
||||
schema.object({ signature: schema.string(), timestamp: schema.number() })
|
||||
|
|
|
@ -135,6 +135,13 @@ export function defineRecordViolations({ router, analyticsService }: RouteDefini
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/analytics/_record_violations',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route is used by browsers to report CSP and Permission Policy violations. These requests are sent without authentication per the browser spec.',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
/**
|
||||
* Chrome supports CSP3 spec and sends an array of reports. Safari only sends a single
|
||||
|
|
|
@ -15,7 +15,17 @@ export function defineAnonymousAccessGetCapabilitiesRoutes({
|
|||
getAnonymousAccessService,
|
||||
}: RouteDefinitionParams) {
|
||||
router.get(
|
||||
{ path: '/internal/security/anonymous_access/capabilities', validate: false },
|
||||
{
|
||||
path: '/internal/security/anonymous_access/capabilities',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the scoped ES cluster client of the anonymous access service',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
async (_context, request, response) => {
|
||||
const anonymousAccessService = getAnonymousAccessService();
|
||||
return response.ok({ body: await anonymousAccessService.getCapabilities(request) });
|
||||
|
|
|
@ -18,7 +18,16 @@ export function defineAnonymousAccessGetStateRoutes({
|
|||
getAnonymousAccessService,
|
||||
}: RouteDefinitionParams) {
|
||||
router.get(
|
||||
{ path: '/internal/security/anonymous_access/state', validate: false },
|
||||
{
|
||||
path: '/internal/security/anonymous_access/state',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route is used for anonymous access',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
async (_context, _request, response) => {
|
||||
const anonymousAccessService = getAnonymousAccessService();
|
||||
const accessURLParameters = anonymousAccessService.accessURLParameters
|
||||
|
|
|
@ -32,6 +32,13 @@ export function defineCreateApiKeyRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/api_key',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the scoped ES cluster client of the internal authentication service',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.oneOf([
|
||||
restApiKeySchema,
|
||||
|
|
|
@ -16,6 +16,13 @@ export function defineEnabledApiKeysRoutes({
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/api_key/_enabled',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the scoped ES cluster client of the internal authentication service',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
|
|
|
@ -22,6 +22,12 @@ export function defineHasApiKeysRoutes({
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/api_key/_has_active',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to the scoped ES cluster client of the internal authentication service, and to Core's ES client`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
options: {
|
||||
access: 'internal',
|
||||
|
|
|
@ -21,6 +21,12 @@ export function defineInvalidateApiKeysRoutes({ router }: RouteDefinitionParams)
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/api_key/invalidate',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's ES client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
apiKeys: schema.arrayOf(schema.object({ id: schema.string(), name: schema.string() })),
|
||||
|
|
|
@ -25,6 +25,12 @@ export function defineQueryApiKeysAndAggregationsRoute({
|
|||
// on behalf of the user making the request and governed by the user's own cluster privileges.
|
||||
{
|
||||
path: '/internal/security/api_key/_query',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to the scoped ES cluster client of the internal authentication service, and to Core's ES client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
query: schema.maybe(schema.object({}, { unknowns: 'allow' })),
|
||||
|
|
|
@ -34,6 +34,12 @@ export function defineUpdateApiKeyRoutes({
|
|||
router.put(
|
||||
{
|
||||
path: '/internal/security/api_key',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to the scoped ES cluster client of the internal authentication service`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.oneOf([
|
||||
updateRestApiKeySchema,
|
||||
|
|
|
@ -43,6 +43,12 @@ export function defineCommonRoutes({
|
|||
router.get(
|
||||
{
|
||||
path,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route must remain accessible to 3rd-party IdPs',
|
||||
},
|
||||
},
|
||||
// Allow unknown query parameters as this endpoint can be hit by the 3rd-party with any
|
||||
// set of query string parameters (e.g. SAML/OIDC logout request/response parameters).
|
||||
validate: { query: schema.object({}, { unknowns: 'allow' }) },
|
||||
|
@ -92,7 +98,17 @@ export function defineCommonRoutes({
|
|||
]) {
|
||||
const deprecated = path === '/api/security/v1/me';
|
||||
router.get(
|
||||
{ path, validate: false, options: { access: deprecated ? 'public' : 'internal' } },
|
||||
{
|
||||
path,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's security service; there must be an authenticated user for this route to return information`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
options: { access: deprecated ? 'public' : 'internal' },
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
if (deprecated) {
|
||||
logger.warn(
|
||||
|
@ -135,10 +151,16 @@ export function defineCommonRoutes({
|
|||
}
|
||||
|
||||
// Register the login route for serverless for the time being. Note: This route will move into the buildFlavor !== 'serverless' block below. See next line.
|
||||
// ToDo: In the serverless environment, we do not support API login - the only valid authentication methodology (or maybe just method or mechanism?) is SAML
|
||||
// ToDo: In the serverless environment, we do not support API login - the only valid authentication type is SAML
|
||||
router.post(
|
||||
{
|
||||
path: '/internal/security/login',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route provides basic and token login capbility, which is delegated to the internal authentication service`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
providerType: schema.string(),
|
||||
|
@ -183,7 +205,16 @@ export function defineCommonRoutes({
|
|||
if (buildFlavor !== 'serverless') {
|
||||
// In the serverless offering, the access agreement functionality isn't available.
|
||||
router.post(
|
||||
{ path: '/internal/security/access_agreement/acknowledge', validate: false },
|
||||
{
|
||||
path: '/internal/security/access_agreement/acknowledge',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to the internal authentication service; there must be an authenticated user for this route to function`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
// If license doesn't allow access agreement we shouldn't handle request.
|
||||
if (!license.getFeatures().allowAccessAgreement) {
|
||||
|
|
|
@ -87,6 +87,12 @@ export function defineOIDCRoutes({
|
|||
router.get(
|
||||
{
|
||||
path,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route must remain accessible to 3rd-party OIDC providers',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
query: schema.object(
|
||||
{
|
||||
|
@ -176,6 +182,12 @@ export function defineOIDCRoutes({
|
|||
router.post(
|
||||
{
|
||||
path,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route must remain accessible to 3rd-party OIDC providers',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object(
|
||||
{
|
||||
|
@ -221,6 +233,12 @@ export function defineOIDCRoutes({
|
|||
router.get(
|
||||
{
|
||||
path: '/api/security/oidc/initiate_login',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route must remain accessible to 3rd-party OIDC providers',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
query: schema.object(
|
||||
{
|
||||
|
|
|
@ -30,6 +30,12 @@ export function defineSAMLRoutes({
|
|||
router.post(
|
||||
{
|
||||
path,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route must remain accessible to 3rd-party SAML providers',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object(
|
||||
{ SAMLResponse: schema.string(), RelayState: schema.maybe(schema.string()) },
|
||||
|
|
|
@ -14,6 +14,13 @@ export function defineGetPrivilegesRoutes({ router, authz }: RouteDefinitionPara
|
|||
router.get(
|
||||
{
|
||||
path: '/api/security/privileges',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route is opted out from authorization because it returns only the global list of Kibana privileges',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
query: schema.object({
|
||||
// We don't use `schema.boolean` here, because all query string parameters are treated as
|
||||
|
|
|
@ -9,7 +9,16 @@ import type { RouteDefinitionParams } from '../..';
|
|||
|
||||
export function defineGetBuiltinPrivilegesRoutes({ router }: RouteDefinitionParams) {
|
||||
router.get(
|
||||
{ path: '/internal/security/esPrivileges/builtin', validate: false },
|
||||
{
|
||||
path: '/internal/security/esPrivileges/builtin',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const esClient = (await context.core).elasticsearch.client;
|
||||
const privileges = await esClient.asCurrentUser.security.getBuiltinPrivileges();
|
||||
|
|
|
@ -25,6 +25,12 @@ export function defineDeleteRolesRoutes({ router }: RouteDefinitionParams) {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.roles.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({ name: schema.string({ minLength: 1 }) }),
|
||||
|
|
|
@ -32,6 +32,12 @@ export function defineGetRolesRoutes({
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.roles.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -33,6 +33,12 @@ export function defineGetAllRolesRoutes({
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.roles.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
query: schema.maybe(
|
||||
|
|
|
@ -52,6 +52,12 @@ export function defineBulkCreateOrUpdateRolesRoutes({
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.roles.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
body: getBulkCreateOrUpdatePayloadSchema(() => {
|
||||
|
|
|
@ -35,6 +35,12 @@ export function definePutRolesRoutes({
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.roles.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -19,6 +19,12 @@ export function defineShareSavedObjectPermissionRoutes({
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/_share_saved_object_permissions',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to the internal authorization service's checkPrivilegesWithRequest function`,
|
||||
},
|
||||
},
|
||||
validate: { query: schema.object({ type: schema.string() }) },
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
|
|
|
@ -23,6 +23,12 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/deprecations/kibana_user_role/_fix_users',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
|
@ -88,6 +94,12 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/deprecations/kibana_user_role/_fix_role_mappings',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
|
|
|
@ -43,6 +43,12 @@ export function defineSecurityFeatureCheckRoute({ router, logger }: RouteDefinit
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/_check_security_features',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
|
|
|
@ -14,6 +14,12 @@ export function defineGetFieldsRoutes({ router }: RouteDefinitionParams) {
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/fields/{query}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: { params: schema.object({ query: schema.string() }) },
|
||||
},
|
||||
async (context, request, response) => {
|
||||
|
|
|
@ -15,6 +15,12 @@ export function defineRoleMappingDeleteRoutes({ router }: RouteDefinitionParams)
|
|||
router.delete(
|
||||
{
|
||||
path: '/internal/security/role_mapping/{name}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({
|
||||
name: schema.string(),
|
||||
|
|
|
@ -18,6 +18,12 @@ export function defineRoleMappingGetRoutes(params: RouteDefinitionParams) {
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/role_mapping/{name?}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({
|
||||
name: schema.maybe(schema.string()),
|
||||
|
|
|
@ -15,6 +15,12 @@ export function defineRoleMappingPostRoutes({ router }: RouteDefinitionParams) {
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/role_mapping/{name}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({
|
||||
name: schema.string(),
|
||||
|
|
|
@ -29,7 +29,16 @@ export function defineSecurityCheckupGetStateRoutes({
|
|||
const doesClusterHaveUserData = createClusterDataCheck();
|
||||
|
||||
router.get(
|
||||
{ path: '/internal/security/security_checkup/state', validate: false },
|
||||
{
|
||||
path: '/internal/security/security_checkup/state',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
async (context, _request, response) => {
|
||||
const esClient = (await context.core).elasticsearch.client;
|
||||
let displayAlert = false;
|
||||
|
|
|
@ -14,6 +14,13 @@ export function defineSessionExtendRoutes({ router, basePath }: RouteDefinitionP
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/session',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route is opted out from authorization because it only redirects to the /internal/security/session endpoint',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
async (_context, _request, response) => {
|
||||
|
|
|
@ -14,7 +14,17 @@ import type { SessionInfo } from '../../../common/types';
|
|||
*/
|
||||
export function defineSessionInfoRoutes({ router, getSession }: RouteDefinitionParams) {
|
||||
router.get(
|
||||
{ path: '/internal/security/session', validate: false },
|
||||
{
|
||||
path: '/internal/security/session',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route is opted out from authorization because a valid session is required, and it does not return sensative session information',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
async (_context, request, response) => {
|
||||
const { value: sessionValue } = await getSession().get(request);
|
||||
if (sessionValue) {
|
||||
|
|
|
@ -20,6 +20,13 @@ export function defineGetCurrentUserProfileRoute({
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/user_profile',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the internal authorization service; a currently authenticated user is required',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
query: schema.object({ dataPath: schema.maybe(schema.string()) }),
|
||||
},
|
||||
|
|
|
@ -27,6 +27,13 @@ export function defineUpdateUserProfileDataRoute({
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/user_profile/_data',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the internal authorization service; an authenticated user and valid session are required',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.recordOf(schema.string(), schema.any()),
|
||||
},
|
||||
|
|
|
@ -24,6 +24,12 @@ export function defineChangeUserPasswordRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/users/{username}/password',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to the internal authorization service and the Security plugin's canUserChangePassword function`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({ username: schema.string({ minLength: 1, maxLength: 1024 }) }),
|
||||
body: schema.object({
|
||||
|
|
|
@ -15,6 +15,12 @@ export function defineCreateOrUpdateUserRoutes({ router }: RouteDefinitionParams
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/users/{username}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({ username: schema.string({ minLength: 1, maxLength: 1024 }) }),
|
||||
body: schema.object({
|
||||
|
|
|
@ -15,6 +15,12 @@ export function defineDeleteUserRoutes({ router }: RouteDefinitionParams) {
|
|||
router.delete(
|
||||
{
|
||||
path: '/internal/security/users/{username}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({ username: schema.string({ minLength: 1, maxLength: 1024 }) }),
|
||||
},
|
||||
|
|
|
@ -15,6 +15,12 @@ export function defineDisableUserRoutes({ router }: RouteDefinitionParams) {
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/users/{username}/_disable',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({ username: schema.string({ minLength: 1, maxLength: 1024 }) }),
|
||||
},
|
||||
|
|
|
@ -15,6 +15,12 @@ export function defineEnableUserRoutes({ router }: RouteDefinitionParams) {
|
|||
router.post(
|
||||
{
|
||||
path: '/internal/security/users/{username}/_enable',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({ username: schema.string({ minLength: 1, maxLength: 1024 }) }),
|
||||
},
|
||||
|
|
|
@ -15,6 +15,12 @@ export function defineGetUserRoutes({ router }: RouteDefinitionParams) {
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/security/users/{username}',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
params: schema.object({ username: schema.string({ minLength: 1, maxLength: 1024 }) }),
|
||||
},
|
||||
|
|
|
@ -11,7 +11,16 @@ import { createLicensedRouteHandler } from '../licensed_route_handler';
|
|||
|
||||
export function defineGetAllUsersRoutes({ router }: RouteDefinitionParams) {
|
||||
router.get(
|
||||
{ path: '/internal/security/users', validate: false },
|
||||
{
|
||||
path: '/internal/security/users',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: `This route delegates authorization to Core's scoped ES cluster client`,
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
try {
|
||||
const esClient = (await context.core).elasticsearch.client;
|
||||
|
|
|
@ -35,7 +35,17 @@ export function defineAccessAgreementRoutes({
|
|||
);
|
||||
|
||||
router.get(
|
||||
{ path: '/internal/security/access_agreement/state', validate: false },
|
||||
{
|
||||
path: '/internal/security/access_agreement/state',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route is opted out from authorization because it requires only an active session in order to function',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
if (!canHandleRequest()) {
|
||||
return response.forbidden({
|
||||
|
|
|
@ -57,7 +57,18 @@ export function defineLoginRoutes({
|
|||
);
|
||||
|
||||
router.get(
|
||||
{ path: '/internal/security/login_state', validate: false, options: { authRequired: false } },
|
||||
{
|
||||
path: '/internal/security/login_state',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route is opted out from authorization because it only provides non-sensative information about authentication provider configuration',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
options: { authRequired: false },
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const { allowLogin, layout = 'form' } = license.getFeatures();
|
||||
const { sortedProviders, selector } = config.authc;
|
||||
|
|
|
@ -49,9 +49,21 @@ describe.skip('onPostAuthInterceptor', () => {
|
|||
*/
|
||||
|
||||
function initKbnServer(router: IRouter, basePath: IBasePath) {
|
||||
router.get({ path: '/api/np_test/foo', validate: false }, (context, req, h) => {
|
||||
return h.ok({ body: { path: req.url.pathname, basePath: basePath.get(req) } });
|
||||
});
|
||||
router.get(
|
||||
{
|
||||
path: '/api/np_test/foo',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route is opted out from authorization',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
(context, req, h) => {
|
||||
return h.ok({ body: { path: req.url.pathname, basePath: basePath.get(req) } });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function request(
|
||||
|
|
|
@ -38,14 +38,32 @@ describe.skip('onRequestInterceptor', () => {
|
|||
|
||||
function initKbnServer(router: IRouter, basePath: IBasePath) {
|
||||
router.get(
|
||||
{ path: '/np_foo', validate: false },
|
||||
{
|
||||
path: '/np_foo',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route is opted out from authorization',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
(context: unknown, req: KibanaRequest, h: KibanaResponseFactory) => {
|
||||
return h.ok({ body: { path: req.url.pathname, basePath: basePath.get(req) } });
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
{ path: '/some/path/s/np_foo/bar', validate: false },
|
||||
{
|
||||
path: '/some/path/s/np_foo/bar',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route is opted out from authorization',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
(context: unknown, req: KibanaRequest, h: KibanaResponseFactory) => {
|
||||
return h.ok({ body: { path: req.url.pathname, basePath: basePath.get(req) } });
|
||||
}
|
||||
|
@ -54,6 +72,12 @@ describe.skip('onRequestInterceptor', () => {
|
|||
router.get(
|
||||
{
|
||||
path: '/i/love/np_spaces',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason: 'This route is opted out from authorization',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
query: schema.object({
|
||||
queryParam: schema.string({
|
||||
|
|
|
@ -31,6 +31,13 @@ export function initDeleteSpacesApi(deps: ExternalRouteDeps) {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -18,6 +18,13 @@ export function initDisableLegacyUrlAliasesApi(deps: ExternalRouteDeps) {
|
|||
router.post(
|
||||
{
|
||||
path: '/api/spaces/_disable_legacy_url_aliases',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
options: {
|
||||
access: isServerless ? 'internal' : 'public',
|
||||
summary: 'Disable legacy URL aliases',
|
||||
|
|
|
@ -28,6 +28,13 @@ export function initGetSpaceApi(deps: ExternalRouteDeps) {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -27,6 +27,13 @@ export function initGetAllSpacesApi(deps: ExternalRouteDeps) {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
query: schema.object({
|
||||
|
|
|
@ -17,6 +17,13 @@ export function initGetShareableReferencesApi(deps: ExternalRouteDeps) {
|
|||
router.post(
|
||||
{
|
||||
path: '/api/spaces/_get_shareable_references',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
options: {
|
||||
access: isServerless ? 'internal' : 'public',
|
||||
summary: `Get shareable references`,
|
||||
|
|
|
@ -30,6 +30,13 @@ export function initPostSpacesApi(deps: ExternalRouteDeps) {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
body: getSpaceSchema(isServerless),
|
||||
|
|
|
@ -29,6 +29,13 @@ export function initPutSpacesApi(deps: ExternalRouteDeps) {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
request: {
|
||||
params: schema.object({
|
||||
|
|
|
@ -40,6 +40,13 @@ export function initUpdateObjectsSpacesApi(deps: ExternalRouteDeps) {
|
|||
router.post(
|
||||
{
|
||||
path: '/api/spaces/_update_objects_spaces',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
options: {
|
||||
access: isServerless ? 'internal' : 'public',
|
||||
summary: `Update saved objects in spaces`,
|
||||
|
|
|
@ -15,6 +15,13 @@ export function initGetActiveSpaceApi(deps: InternalRouteDeps) {
|
|||
router.get(
|
||||
{
|
||||
path: '/internal/spaces/_active_space',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service getActiveSpace API, which uses a scoped spaces client',
|
||||
},
|
||||
},
|
||||
validate: false,
|
||||
},
|
||||
createLicensedRouteHandler(async (context, request, response) => {
|
||||
|
|
|
@ -37,6 +37,13 @@ export function initSetSolutionSpaceApi(deps: InternalRouteDeps) {
|
|||
router.put(
|
||||
{
|
||||
path: '/internal/spaces/space/{id}/solution',
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This route delegates authorization to the spaces service via a scoped spaces client',
|
||||
},
|
||||
},
|
||||
options: {
|
||||
description: `Update solution for a space`,
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue