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

Provide sensible defaults for xpack.security.session.{lifespan|idleTimeout}. #106061

Merged
merged 2 commits into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions docs/settings/security-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ You can configure the following settings in the `kibana.yml` file.

|[[xpack-session-idleTimeout]] `xpack.security.session.idleTimeout` {ess-icon}
| Ensures that user sessions will expire after a period of inactivity. This and <<xpack-session-lifespan,`xpack.security.session.lifespan`>> are both
highly recommended. You can also specify this setting for <<xpack-security-provider-session-idleTimeout, every provider separately>>. If this is _not_ set or set to `0`, then sessions will never expire due to inactivity. By default, this setting is not set.
highly recommended. You can also specify this setting for <<xpack-security-provider-session-idleTimeout, every provider separately>>. If this is set to `0`, then sessions will never expire due to inactivity. By default, this value is 1 hour.

2+a|
[TIP]
Expand All @@ -281,8 +281,8 @@ Use a string of `<count>[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w

|[[xpack-session-lifespan]] `xpack.security.session.lifespan` {ess-icon}
| Ensures that user sessions will expire after the defined time period. This behavior is also known as an "absolute timeout". If
this is _not_ set or set to `0`, user sessions could stay active indefinitely. This and <<xpack-session-idleTimeout, `xpack.security.session.idleTimeout`>> are both highly
recommended. You can also specify this setting for <<xpack-security-provider-session-lifespan, every provider separately>>. By default, this setting is not set.
this is set to `0`, user sessions could stay active indefinitely. This and <<xpack-session-idleTimeout, `xpack.security.session.idleTimeout`>> are both highly
recommended. You can also specify this setting for <<xpack-security-provider-session-lifespan, every provider separately>>. By default, this value is 30 days.

2+a|
[TIP]
Expand Down
8 changes: 4 additions & 4 deletions docs/user/security/session-management.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ To manage user sessions programmatically, {kib} exposes <<session-management-api
==== Session idle timeout

You can use `xpack.security.session.idleTimeout` to expire sessions after a period of inactivity. This and `xpack.security.session.lifespan` are both highly recommended.
By default, sessions don't expire because of inactivity. To define a sliding session expiration, set the property in the `kibana.yml` configuration file. The idle timeout is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '20m', '24h', '7d', '1w'). For example, set the idle timeout to expire sessions after 1 hour of inactivity:
By default, sessions expire after 1 hour of inactivity. To define another value for a sliding session expiration, set the property in the `kibana.yml` configuration file. The idle timeout is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '20m', '24h', '7d', '1w'). For example, set the idle timeout to expire sessions after 30 minutes of inactivity:

--
[source,yaml]
--------------------------------------------------------------------------------
xpack.security.session.idleTimeout: "1h"
xpack.security.session.idleTimeout: "30m"
--------------------------------------------------------------------------------
--

[[session-lifespan]]
==== Session lifespan

You can use `xpack.security.session.lifespan` to configure the maximum session duration or "lifespan" -- also known as the "absolute timeout". This and `xpack.security.session.idleTimeout` are both highly recommended. By default, sessions don't have a fixed lifespan, and if an idle timeout is defined, a session can still be extended indefinitely. To define a maximum session lifespan, set the property in the `kibana.yml` configuration file. The lifespan is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '20m', '24h', '7d', '1w'). For example, set the lifespan to expire sessions after 30 days:
You can use `xpack.security.session.lifespan` to configure the maximum session duration or "lifespan" -- also known as the "absolute timeout". This and `xpack.security.session.idleTimeout` are both highly recommended. By default, a maximum session lifespan is 30 days. To define another lifespan, set the property in the `kibana.yml` configuration file. The lifespan is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '20m', '24h', '7d', '1w'). For example, set the lifespan to expire sessions after 7 days:

--
[source,yaml]
--------------------------------------------------------------------------------
xpack.security.session.lifespan: "30d"
xpack.security.session.lifespan: "7d"
--------------------------------------------------------------------------------
--

Expand Down
54 changes: 30 additions & 24 deletions x-pack/plugins/security/server/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ describe('config schema', () => {
"secureCookies": false,
"session": Object {
"cleanupInterval": "PT1H",
"idleTimeout": "PT1H",
"lifespan": "P30D",
},
}
`);
Expand Down Expand Up @@ -110,6 +112,8 @@ describe('config schema', () => {
"secureCookies": false,
"session": Object {
"cleanupInterval": "PT1H",
"idleTimeout": "PT1H",
"lifespan": "P30D",
},
}
`);
Expand Down Expand Up @@ -158,6 +162,8 @@ describe('config schema', () => {
"secureCookies": false,
"session": Object {
"cleanupInterval": "PT1H",
"idleTimeout": "PT1H",
"lifespan": "P30D",
},
}
`);
Expand Down Expand Up @@ -1615,11 +1621,11 @@ describe('createConfig()', () => {
it('returns default values if neither global nor provider specific settings are set', async () => {
expect(createMockConfig().session.getExpirationTimeouts({ type: 'basic', name: 'basic1' }))
.toMatchInlineSnapshot(`
Object {
"idleTimeout": null,
"lifespan": null,
}
`);
Object {
"idleTimeout": "PT1H",
"lifespan": "P30D",
}
`);
});

it('correctly handles explicitly disabled global settings', async () => {
Expand Down Expand Up @@ -1653,23 +1659,23 @@ describe('createConfig()', () => {
name: 'basic1',
})
).toMatchInlineSnapshot(`
Object {
"idleTimeout": "PT0.123S",
"lifespan": null,
}
`);
Object {
"idleTimeout": "PT0.123S",
"lifespan": "P30D",
}
`);

expect(
createMockConfig({ session: { lifespan: 456 } }).session.getExpirationTimeouts({
type: 'basic',
name: 'basic1',
})
).toMatchInlineSnapshot(`
Object {
"idleTimeout": null,
"lifespan": "PT0.456S",
}
`);
Object {
"idleTimeout": "PT1H",
"lifespan": "PT0.456S",
}
`);

expect(
createMockConfig({
Expand All @@ -1692,7 +1698,7 @@ describe('createConfig()', () => {
).toMatchInlineSnapshot(`
Object {
"idleTimeout": "PT0.123S",
"lifespan": null,
"lifespan": "P30D",
}
`);

Expand All @@ -1703,7 +1709,7 @@ describe('createConfig()', () => {
})
).toMatchInlineSnapshot(`
Object {
"idleTimeout": null,
"idleTimeout": "PT1H",
"lifespan": "PT0.456S",
}
`);
Expand Down Expand Up @@ -1734,14 +1740,14 @@ describe('createConfig()', () => {
.toMatchInlineSnapshot(`
Object {
"idleTimeout": "PT0.321S",
"lifespan": null,
"lifespan": "P30D",
}
`);
expect(configWithoutGlobal.session.getExpirationTimeouts({ type: 'saml', name: 'saml1' }))
.toMatchInlineSnapshot(`
Object {
"idleTimeout": "PT5M32.211S",
"lifespan": null,
"lifespan": "P30D",
}
`);

Expand All @@ -1758,14 +1764,14 @@ describe('createConfig()', () => {
.toMatchInlineSnapshot(`
Object {
"idleTimeout": "PT0.321S",
"lifespan": null,
"lifespan": "P30D",
}
`);
expect(configWithGlobal.session.getExpirationTimeouts({ type: 'saml', name: 'saml1' }))
.toMatchInlineSnapshot(`
Object {
"idleTimeout": "PT5M32.211S",
"lifespan": null,
"lifespan": "P30D",
}
`);
});
Expand All @@ -1783,14 +1789,14 @@ describe('createConfig()', () => {
expect(configWithoutGlobal.session.getExpirationTimeouts({ type: 'basic', name: 'basic1' }))
.toMatchInlineSnapshot(`
Object {
"idleTimeout": null,
"idleTimeout": "PT1H",
"lifespan": "PT0.654S",
}
`);
expect(configWithoutGlobal.session.getExpirationTimeouts({ type: 'saml', name: 'saml1' }))
.toMatchInlineSnapshot(`
Object {
"idleTimeout": null,
"idleTimeout": "PT1H",
"lifespan": "PT11M5.544S",
}
`);
Expand All @@ -1807,7 +1813,7 @@ describe('createConfig()', () => {
expect(configWithGlobal.session.getExpirationTimeouts({ type: 'basic', name: 'basic1' }))
.toMatchInlineSnapshot(`
Object {
"idleTimeout": null,
"idleTimeout": "PT1H",
"lifespan": "PT0.654S",
}
`);
Expand Down
23 changes: 7 additions & 16 deletions x-pack/plugins/security/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,12 @@ export const ConfigSchema = schema.object({
schema.string({ minLength: 32, defaultValue: 'a'.repeat(32) })
),
session: schema.object({
idleTimeout: schema.maybe(schema.oneOf([schema.duration(), schema.literal(null)])),
lifespan: schema.maybe(schema.oneOf([schema.duration(), schema.literal(null)])),
idleTimeout: schema.oneOf([schema.duration(), schema.literal(null)], {
defaultValue: schema.duration().validate('1h'),
}),
lifespan: schema.oneOf([schema.duration(), schema.literal(null)], {
defaultValue: schema.duration().validate('30d'),
}),
cleanupInterval: schema.duration({
defaultValue: '1h',
validate(value) {
Expand Down Expand Up @@ -385,29 +389,16 @@ export function createConfig(
}

function getSessionConfig(session: RawConfigType['session'], providers: ProvidersConfigType) {
const defaultAnonymousSessionLifespan = schema.duration().validate('30d');
return {
cleanupInterval: session.cleanupInterval,
getExpirationTimeouts({ type, name }: AuthenticationProvider) {
// Both idle timeout and lifespan from the provider specific session config can have three
// possible types of values: `Duration`, `null` and `undefined`. The `undefined` type means that
// provider doesn't override session config and we should fall back to the global one instead.
const providerSessionConfig = providers[type as keyof ProvidersConfigType]?.[name]?.session;

// We treat anonymous sessions differently since users can create them without realizing it. This may lead to a
// non controllable amount of sessions stored in the session index. To reduce the impact we set a 30 days lifespan
// for the anonymous sessions in case neither global nor provider specific lifespan is configured explicitly.
// We can remove this code once https://github.com/elastic/kibana/issues/68885 is resolved.
const providerLifespan =
type === 'anonymous' &&
providerSessionConfig?.lifespan === undefined &&
session.lifespan === undefined
? defaultAnonymousSessionLifespan
: providerSessionConfig?.lifespan;
azasypkin marked this conversation as resolved.
Show resolved Hide resolved

const [idleTimeout, lifespan] = [
[session.idleTimeout, providerSessionConfig?.idleTimeout],
[session.lifespan, providerLifespan],
[session.lifespan, providerSessionConfig?.lifespan],
].map(([globalTimeout, providerTimeout]) => {
const timeout = providerTimeout === undefined ? globalTimeout ?? null : providerTimeout;
return timeout && timeout.asMilliseconds() > 0 ? timeout : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ describe('Session', () => {
session = new Session({
logger: loggingSystemMock.createLogger(),
config: createConfig(
ConfigSchema.validate({ session: { idleTimeout: 123 } }),
ConfigSchema.validate({ session: { idleTimeout: 123, lifespan: null } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
Expand Down Expand Up @@ -398,7 +398,7 @@ describe('Session', () => {
session = new Session({
logger: loggingSystemMock.createLogger(),
config: createConfig(
ConfigSchema.validate({ session: { lifespan } }),
ConfigSchema.validate({ session: { idleTimeout: null, lifespan } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
Expand Down Expand Up @@ -472,9 +472,11 @@ describe('Session', () => {

session = new Session({
logger: loggingSystemMock.createLogger(),
config: createConfig(ConfigSchema.validate({}), loggingSystemMock.createLogger(), {
isTLSEnabled: false,
}),
config: createConfig(
ConfigSchema.validate({ session: { idleTimeout: null, lifespan: null } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
sessionCookie: mockSessionCookie,
sessionIndex: mockSessionIndex,
});
Expand Down Expand Up @@ -527,7 +529,7 @@ describe('Session', () => {
session = new Session({
logger: loggingSystemMock.createLogger(),
config: createConfig(
ConfigSchema.validate({ session: { idleTimeout: 123 } }),
ConfigSchema.validate({ session: { idleTimeout: 123, lifespan: null } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
Expand Down Expand Up @@ -718,7 +720,7 @@ describe('Session', () => {
session = new Session({
logger: loggingSystemMock.createLogger(),
config: createConfig(
ConfigSchema.validate({ session: { lifespan } }),
ConfigSchema.validate({ session: { idleTimeout: null, lifespan } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ describe('Session index', () => {
const sessionIndexOptions = {
logger: loggingSystemMock.createLogger(),
kibanaIndexName: '.kibana_some_tenant',
config: createConfig(ConfigSchema.validate({}), loggingSystemMock.createLogger(), {
isTLSEnabled: false,
}),
config: createConfig(
ConfigSchema.validate({ session: { idleTimeout: null, lifespan: null } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
elasticsearchClient: mockElasticsearchClient,
};

Expand Down Expand Up @@ -239,7 +241,7 @@ describe('Session index', () => {
logger: loggingSystemMock.createLogger(),
kibanaIndexName: '.kibana_some_tenant',
config: createConfig(
ConfigSchema.validate({ session: { lifespan: 456 } }),
ConfigSchema.validate({ session: { idleTimeout: null, lifespan: 456 } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
Expand Down Expand Up @@ -315,7 +317,7 @@ describe('Session index', () => {
logger: loggingSystemMock.createLogger(),
kibanaIndexName: '.kibana_some_tenant',
config: createConfig(
ConfigSchema.validate({ session: { idleTimeout } }),
ConfigSchema.validate({ session: { idleTimeout, lifespan: null } }),
loggingSystemMock.createLogger(),
{ isTLSEnabled: false }
),
Expand Down