-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Implement AnonymousAuthenticationProvider. #79985
Implement AnonymousAuthenticationProvider. #79985
Conversation
Pinging @elastic/kibana-security (Team:Security) |
e8efe55
to
96a3d27
Compare
@azasypkin This looks solid! A couple of initial thoughts and questions:
|
Thanks for looking into this @arisonl !
Yep, I don't anticipate any problems with the UX for the time being, except for the case when we have multiple providers and explicitly disabled login selector.
Correct.
There are only two possibilities here: either we provide a special URL user can go to (like we did with
Awesome, thanks!
Well, actually I don't rely on a native ES anonymous access here at all. That means that the other option is to actually somehow leverage it, but IMO it makes overall setup a bit more complex:
Yeah, these are all interesting ideas! I'm not sure if we can do that technically in all cases since anonymous user/API key can be created before Kibana knows that it will be used for that purpose, but let's explore this too.
We can create user, but it's actually the easiest part. The complex part is to define roles that we cannot figure out automatically. Also if we create something automatically we should remove it automatically as well if anonymous access is disabled, and that may not be easy to do or not something Kibana admins want us to do. If we get feedback that anonymous access in Kibana is used very frequently we can even invest some time and introduce something like
Can't think of anything at the moment except for the new entries to the provider allow-list. |
Exactly, the embedding scenario comes into play here.
What are you thinking in terms of roles? Because if we can frame it somehow and if it is feasible, it sounds safer than creating an anon user and allow admins to assign just any role. |
I mean we cannot know the privileges admins want to give anonymous users, they may want to allow access to a Dashboard, or to a Discover, or to a Canvas, or ML, or any other permutation of the features Kibana offers. It doesn't seem like we can make a reasonable decision on our own. Moreover, they may want to give several roles (e.g. give a |
Gogogo! :) Thanks for adding this - can't wait for this being available in elastic cloud! |
892b88a
to
5801797
Compare
02d2c17
to
788cad6
Compare
Full-disclosure, this question is solely based on reading the description in the PR, and I haven't taken a look at the code or tried it out myself, I'm being super lazy, apologies. How do you anticipate anonymous access working for consumers of Kibana's HTTP APIs? Is my understanding correct that some credentials are still be required as part of the HTTP request, but it'd be possible to hit the login endpoint with no credentials and get a cookie that can be used for subsequent requests? |
Yep, that would certainly be possible, similarly to how you'd use PKI and Kerberos for API access. I'd treat this as a workaround though: if API access is needed then I'd expect users to leverage HTTP authentication instead (with Using anonymous access to purely interact with Kibana APIs isn't something I prioritized just yet based on the use cases we know about. But if we feel a strong need to support that I'd probably leverage a custom What do you think? Would cookie-based workaround be enough to cover the use cases you have in mind? |
788cad6
to
416ad27
Compare
I think the approach you've outlined would be a lot easier to consume than the cookie-based approach. My primary concern stemmed from the inherent differences between how Kibana's HTTP APIs will behave when it's using anonymous access vs Elasticsearch. AFAIK, when a HTTP request to Elasticsearch doesn't contain authorization credentials and Elasticsearch is configured for anonymous access, it will use the anonymous user. I don't think it's required for us to replicate the Elasticsearch approach, and I've struggled to think of any use-cases that would absolutely require we do so. The ability to specify the |
I'd even argue that in the Kibana context the current ES behavior may be a bit surprising since there is no clear indication of the user intent to use anonymous access for the particular request (unlike requests with
Good, let's wait for the initial reaction/feedback then. |
416ad27
to
c0b7b43
Compare
c0b7b43
to
03d11a3
Compare
+1 what Larry said. Will check it out tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kibana-QA changes LGTM. I started flaky-test-runner to check tests stability:
https://kibana-ci.elastic.co/job/kibana+flaky-test-suite-runner/1013/
https://kibana-ci.elastic.co/job/kibana+flaky-test-suite-runner/1014/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested a bunch of different scenarios (both auth modes, different access levels and provider orderings), and this is looking fantastic!
function isAPIKeyCredentials( | ||
credentials: UsernameAndPasswordCredentials | APIKeyCredentials | ||
): credentials is APIKeyCredentials { | ||
const apiKey = ((credentials as unknown) as Record<string, any>).apiKey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we can simplify this cast:
const apiKey = ((credentials as unknown) as Record<string, any>).apiKey; | |
const apiKey = (credentials as APIKeyCredentials).apiKey; |
}), | ||
schema.object({ | ||
username: schema.maybe(schema.string()), | ||
apiKey: schema.string(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worry about the usability of a single apiKey
field. We've found that users have a hard time doing the base64(id + ':' + key)
correctly, and I feel like we'd be in a better place to do that for them. What do you think about exposing two fields for the id and key, so that we can encode it properly? That would be more consistent with the username
/password
approach, as we don't require them to transform those credentials into their base64 equivalent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, we can go this way too. The reasons why I picked another approach initially are:
- Single string for an API key is widely known pattern
- I was thinking that in our API key management UI we'll be displaying already concatenated and encoded key that's ready to use
- Users may already have existing concatenated and encodes keys, I thought that most of the users will store them in that form.
What about more flexible schema instead?
apiKey: schema.oneOf([
schema.object({ key: schema.string(), id: schema.string() }),
schema.string(),
]),
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that in our API key management UI we'll be displaying already concatenated and encoded key that's ready to use
Yeah I think that's something we can and should do when the API Key is first created - we don't have anything like that just yet though.
Single string for an API key is widely known pattern
Users may already have existing concatenated and encodes keys, I thought that most of the users will store them in that form.
Both of these are fair points. I guess it'll come down to how familiar the administrator is with ES API Keys when they go to configure anonymous access.
What about more flexible schema instead?
I like it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it!
Good 👍 Will update schema then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
this.logger.debug( | ||
`Request to ${request.url.pathname}${request.url.search} has been authenticated.` | ||
); | ||
return AuthenticationResult.succeeded(username ? { ...user, username } : user, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question what is the use case for overriding the username of the user who created the API Key?
I worry this will give our users a false sense of confidentiality -- a simple call to /_security/_authenticate
via dev tools (or a rogue plugin making their own API calls) will reveal the true identity.
They might also not understand the importance of the username
-- for example, if you changed the displayed username to elastic
, then (I think) you'll see all reports generated by the real elastic
user. Likewise, the real elastic user will see all reports generated by their anonymous users.
^^ When trying to test the above, I found that it doesn't seem to be overriding the username consistently. For example, I'm seeing audit logs for the canonical username as opposed to the overridden username. Was that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question what is the use case for overriding the username of the user who created the API Key?
Yeah, I'm not entirely sure we need this either. But since initial UX proposal I've got implied that Profile link/page should stay even for anonymous users I wanted to display something there. And displaying the name of the user that created API key would also be confusing, so it's purely UI thing.
I'm wondering if we ES API keys API can be changed to allow us to specify username that should be associated with the API key.
They might also not understand the importance of the username -- for example, if you changed the displayed username to elastic, then (I think) you'll see all reports generated by the real elastic user. Likewise, the real elastic user will see all reports generated by their anonymous users.
Hmmm, I'd be really surprised if we base our checks on the username (ignoring authentication realms) 🙈 I'll double check if it's the case if we happen to keep this username
.
For example, I'm seeing audit logs for the canonical username as opposed to the overridden username. Was that intentional?
You mean Kibana audit logs? If so, then it's not intentional, and I'd say it's even concerning since audit logging should get username only from AuthenticatedUser
. That's a good catch, let me see where this coming from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean Kibana audit logs? If so, then it's not intentional, and I'd say it's even concerning since audit logging should get username only from AuthenticatedUser. That's a good catch, let me see where this coming from.
Hmm, yeah, it's coming from the response of shield.hasPrivileges
and we use it in the audit events. This doesn't look like something that'd be easy to change. Do you think we can just drop this idea with overriding username and see what our users say and then get back to it only if it becomes a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we can just drop this idea with overriding username and see what our users say and then get back to it only if it becomes a problem?
++ yeah I think we should drop the username override for now, and re-evaluate if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
// If authentication succeeded we should return some state to create a session, that will reuse for all subsequent | ||
// requests and anonymous user interactions with the Kibana. | ||
return isAPIKeyCredentials(this.credentials) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about doing a check after authenticating, to make sure that the anonymous user isn't too powerful? An anonymous user with the manage_security
cluster privilege is potentially dangerous to have, so I wonder if we should take steps to prevent that from happening. Having manage_security
is just a couple of clicks away from having superuser
access -- and once the anonymous user has superuser
, the cluster is essentially public/unprotected.
We can consider this for a followup as well. This might be something that we only check if other auth providers are enabled. If the only option is anonymous, then maybe they really don't care that everyone is a superuser 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, I definitely agree that we should build a safety net around anonymous access!
But I was thinking about this as a part of a broader initiative around the security center where we could display things like this to the users who are actually authorized to act on them (e.g. administrators). If we offload that work to the security center or alike we can implement more sophisticated heuristics since even though manage_security
is dangerous it's not the only thing that can do harm.
I'm also hesitant to do that additional check for every request that requires authentication for performance reasons knowing that it may not actually prevent damage in the end...
I tend to move discussion of the possible ideas and solutions to the followup. Does that sound good to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tend to move discussion of the possible ideas and solutions to the followup. Does that sound good to you?
tl;dr Yes, let's take this to a followup!
But I was thinking about this as a part of a broader initiative around the security center where we could display things like this to the users who are actually authorized to act on them (e.g. administrators). If we offload that work to the security center or alike we can implement more sophisticated heuristics since even though manage_security is dangerous it's not the only thing that can do harm.
I certainly see the benefit of including these types of checks within the security center. Keep in mind though that a powerful anonymous user could choose to dismiss these checks so the real administrator might not notice.
I'm also hesitant to do that additional check for every request that requires authentication for performance reasons knowing that it may not actually prevent damage in the end...
I agree - I was thinking we could only check on login
, rather than on every call to authenticate
. It's less than perfect, but would give us reasonable protection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep in mind though that a powerful anonymous user could choose to dismiss these checks so the real administrator might not notice.
That's a good point. We can also design security center in a way that important actions/warnings won't go unnoticed by others in the admin group though, but it's an orthogonal topic anyway.
I agree - I was thinking we could only check on login, rather than on every call to authenticate. It's less than perfect, but would give us reasonable protection.
I see, let's discuss pros and cons in the follow-up then.
@@ -120,6 +129,38 @@ const providersConfigSchema = schema.object( | |||
schema.object({ ...getCommonProviderSchemaProperties(), realm: schema.string() }) | |||
) | |||
), | |||
anonymous: getUniqueProviderSchema( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reminder don't forget docs for these new settings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure (and allow-list update for Cloud as well)! Depending on how review goes I'll either add docs to this PR or move to a separate one.
}); | ||
|
||
it('should fail if `Authorization` header is present, but not valid', async () => { | ||
const spnegoResponse = await supertest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: is spnegoResponse
a copy/paste error from the Kerberos suite?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, thanks! Will fix.
@@ -131,12 +131,18 @@ export class SecurityNavControl extends Component<Props, State> { | |||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question Do you think it still makes sense to show the Profile link for anonymous users? This would only end up showing them an "implementation detail" of the cluster's anonymous access setup -- in other words, we show the underlying user, which might not always make sense to them.
Instead of the profile link, we could show a message indicating that they're using Kibana as an anonymous user/guest, which would give more context to the new "Log in" button that we show them here. (@ryankeairns thoughts?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, I'll hide it then!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -360,6 +387,32 @@ export class LoginForm extends Component<Props, State> { | |||
return null; | |||
}; | |||
|
|||
private renderAutoLoginOverlay = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this overlay, what do you think about doing something a little simpler? The <EuiLoadingContent />
draws my attention away from the smaller "Authenticating..." text below, and almost gives the impression that I'm waiting on the login screen to finish loading.
diff --git a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx
index 346bc6e7d2c..e8d84b5935e 100644
--- a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx
+++ b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx
@@ -25,7 +25,6 @@ import {
EuiLoadingSpinner,
EuiLink,
EuiHorizontalRule,
- EuiLoadingContent,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
@@ -389,27 +388,19 @@ export class LoginForm extends Component<Props, State> {
private renderAutoLoginOverlay = () => {
return (
- <Fragment>
- <EuiPanel data-test-subj="loginSelector" paddingSize="none">
- {this.props.selector.providers.map(() => (
- <EuiLoadingContent className="secLoginCard secLoginCard-autoLogin" lines={2} />
- ))}
- </EuiPanel>
- <EuiSpacer />
- <EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="m" responsive={false}>
- <EuiFlexItem grow={false}>
- <EuiText size="s" className="eui-textCenter">
- <FormattedMessage
- id="xpack.security.loginPage.autoLoginAuthenticatingLabel"
- defaultMessage="Authenticating…"
- />
- </EuiText>
- </EuiFlexItem>
- <EuiFlexItem grow={false}>
- <EuiLoadingSpinner size="m" />
- </EuiFlexItem>
- </EuiFlexGroup>
- </Fragment>
+ <EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="m" responsive={false}>
+ <EuiFlexItem grow={false}>
+ <EuiLoadingSpinner size="l" />
+ </EuiFlexItem>
+ <EuiFlexItem grow={false}>
+ <EuiText size="m" className="eui-textCenter">
+ <FormattedMessage
+ id="xpack.security.loginPage.autoLoginAuthenticatingLabel"
+ defaultMessage="Authenticating..."
+ />
+ </EuiText>
+ </EuiFlexItem>
+ </EuiFlexGroup>
);
};
@ryankeairns might have better ideas when he reviews, so don't take mine as the "winning" suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current behavior is actually based on the UX proposed by @ryankeairns 🙂 I think the intention was to better support both success and failure scenarios when overlay must transition to the full login selector with all the options, but let's wait for the Ryan input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 Do we anticipate the failure state to be infrequent? Perhaps I overestimated how often users would land on the log in selector/list when under the auto log in scenario. The benefit of the current loading design is that it foreshadows what is coming; however, if that doesn't materialize 99% of the time then I can see going with Larry's simpler suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we anticipate the failure state to be infrequent?
I don't think anyone knows that yet. We definitely hope that fail rate will be on the low side, but failures will definitely happen (ES unavailability, license issues and so on). Both UI proposal work for me (I'm more concerned about Loading Elastic
screens before and after this screen to be honest 🙂 ).
however, if that doesn't materialize 99% of the time then I can see going with Larry's simpler suggestion.
Okay, let's optimistically say that it'll be the case and see how it goes. I'll make that change then. Thanks everyone!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. And updated gifs in the issue description.
public render() { | ||
if (this.isLoadingState(LoadingStateType.AutoLogin)) { | ||
return this.renderAutoLoginOverlay(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add unit tests to cover the auto-login scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely, I expected a bit more back and forth on this particular UI change. Once we know how it should look like I'll add a test to cover that 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Thanks @dmlemeshko! Looks like we're good here:
Executions: 40, Failures: 0
Executions: 20, Failures: 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving with two small recommendations.
@@ -41,6 +41,14 @@ | |||
+ .secLoginCard { | |||
border-top: $euiBorderThin; | |||
} | |||
|
|||
&.secLoginCard-autoLogin { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this be removed once the loading state is simplified as proposed by Larry?
If it remains for some other use, then we should tweak this name. The single -
is intended for modifiers/states (e.g. isLoading
). If this is simply a variation on the layout, then we could simply change to __autoLogin
, for exmple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this be removed once the loading state is simplified as proposed by Larry?
Yep, we don't need this anymore.
If it remains for some other use, then we should tweak this name. The single - is intended for modifiers/states (e.g. isLoading). If this is simply a variation on the layout, then we could simply change to __autoLogin, for exmple.
Good to know! I was torn on this, in the code auto-login is treated as one of the loading states, but at the same time it's represented as a completely different layout too.
border-color: transparent; | ||
|
||
+ .secLoginCard { | ||
padding-top: unset; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be supported well enough - since we no longer support IE - but setting this to 0
or inherit
likely achieves the same result in a potentially more sure proof manner.
…ls, use simpler auto login overlay, hide profile link, add login form tests.
@legrego PR should be ready for another review round, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - great work, Aleh!
`); | ||
}); | ||
|
||
it('requires both `id` and `key` in extend `apiKey` format credentials', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
it('requires both `id` and `key` in extend `apiKey` format credentials', () => { | |
it('requires both `id` and `key` in extended `apiKey` format credentials', () => { |
- [credentials.0.username]: expected value of type [string] but got [undefined] | ||
- [credentials.1.apiKey]: types that failed validation: | ||
- [credentials.apiKey.0.key]: expected value of type [string] but got [undefined] | ||
- [credentials.apiKey.1]: expected value of type [string] but got [Object]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of scope for this PR, but I'd love to see us provide more helpful error messages for some of these scenarios. We've all trained ourselves how to read these, but they're not easy to understand once the schemas become moderately complex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
++, these messages have gone out of control. If there is no easy way to improve kbn/config-schema then we'll use custom validation functions that would return less cryptic and more actionable messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue for kbn/config-schema: #84264
* @param request Request instance. | ||
* @param state State value previously stored by the provider. | ||
*/ | ||
private async authenticateViaAuthorizationHeader(request: KibanaRequest, state?: unknown) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the simplifications you made to this provider in the second review round!
# Conflicts: # test/functional/services/common/browser.ts
* master: (67 commits) [Observability] Load hasData call asynchronously (elastic#80644) Implement AnonymousAuthenticationProvider. (elastic#79985) Deprecate `visualization:colorMapping` advanced setting (elastic#83372) [TSVB] [Rollup] Table tab not working with rollup indexes (elastic#83635) Revert "[Search] Search batching using bfetch (elastic#83418)" (elastic#84037) skip flaky suite (elastic#83772) skip flaky suite (elastic#69849) create kbn-legacy-logging package (elastic#77678) [Search] Search batching using bfetch (elastic#83418) [Security Solution] Refactor Timeline flyout to take a full page (elastic#82033) Drop use of console-stamp (elastic#83922) skip flaky suite (elastic#84011 , elastic#84012) Fixed usage of `isReady` for usage collection of alerts and actions (elastic#83760) [maps] support URL drilldowns (elastic#83732) Revert "Added default dedupKey value as an {{alertInstanceId}} to provide grouping functionality for PagerDuty incidents. (elastic#83226)" [code coverage] Update jest config to collect more data (elastic#83804) Added default dedupKey value as an {{alertInstanceId}} to provide grouping functionality for PagerDuty incidents. (elastic#83226) [Security Solution] Give notice when endpoint policy is out of date (elastic#83469) [Security Solution] Sync url state on any changes to query string (elastic#83314) [CI] Initial TeamCity implementation (elastic#81043) ...
7.x/7.11.0: 751b7f2 |
Hello, would this functionality enable a customer to display "end customer" specific information on dashboards on its customer portal? |
Hi @pboulanger74, If understand your use case correctly then what you need isn't anonymous access, but SSO (e.g. SAML or OIDC). In this case when user logs in to the portal that embeds Kibana dashboard, they will automatically log in to Kibana using the same Identity Provider session and hence Kibana/Elasticsearch will know who the user is exactly. The second part would be to setup the field and document level security so that relevant data is filtered based on the name of the current user. It should be possible to achieve since 6.x I believe. |
💔 Build Failed
Failed CI StepsTest FailuresChrome X-Pack UI Functional Tests.x-pack/test/functional/apps/ml/anomaly_detection/annotations·ts.machine learning anomaly detection annotations displays error on broken annotation index and recovers after fixStandard Out
Stack Trace
X-Pack API Integration Tests.x-pack/test/api_integration/apis/ml/results/get_anomalies_table_data·ts.apis Machine Learning ResultsService GetAnomaliesTableData should fetch anomalies table dataStandard Out
Stack Trace
X-Pack API Integration Tests.x-pack/test/api_integration/apis/ml/results/get_anomalies_table_data·ts.apis Machine Learning ResultsService GetAnomaliesTableData should fetch anomalies table dataStandard Out
Stack Trace
Metrics [docs]Module Count
Async chunks
Distributable file count
Page load bundle
History
To update your PR or re-run it, just comment with: |
Summary
Disclaimer: we don't leverage Elasticsearch built-in anonymous access functionality (support of this option was later added in #84074).
The main goal is to provide a well-integrated, built-in alternative to a dedicated proxy in front of Kibana that our users historically used to achieve anonymous-like access. The would reduce a number of moving parts in the Kibana setup and open a plenty of opportunities to integrate anonymous access with other parts of Kibana that would lead to a better security and user experience overall.
Requirements
Since it's a new feature we can define any requirements for this we think are reasonable and can increase safety overall, even for anonymous access:
It can only be configured using new
authc.providers
format. We need this since anonymous access can be a complimentary to another non-anonymous authentication mechanism, for example we can configure both SAML and anonymous at the same time and we'll need to present both at the login screen using differenticon
,description
(e.g.Log in as an Employee
andLogin as a Guest
),hint
and maybe evenaccessAgreement
.It can only be enabled if TLS between Kibana and Elasticsearch is setup. We'll likely need to rely on access tokens and/or API keys under the hood and Elasticsearch requires TLS for that to work in production.(abandoned this idea due to complexity and unnecessary overhead, TLS would still be required is users want to use ApiKey instead of username/password credentials)Every anonymous user will have an anonymous session associated with them. Such sessions won't have an idle timeout, but will have a fixed lifespan by default.
Scenarios
We need to support many different scenarios:
AuthenticatedUser
may give enough information to other plugins to decided whether certain functionality should be available or not.Setup
Username and password
anonymous
and passwordanonymous
:manage_security
privilege and create thatanonymous
user with the specified password and assign any roles you wish anonymous users to have and you're done.Kibana will not store credentials in the session, but will send them to Elasticsearch with every "anonymous" access.
API key
manage_api_key
privilege and create an API key with the required privileges:$ echo -n 'id:api_key' | base64
) and you're done:Auto Login
Users may want to leverage anonymous access when they embed Kibana or share a link to it. This will work out of the box when anonymous is the only authentication mechanism enabled in Kibana or when it's configured as the first one in a multi-provider scenario with disabled Login Selector. In all other scenarios user will need to explicitly express their intention to use anonymous access. Such intention should be expressed through
auth_provider_hint=<provider-name>
query string parameter. At the first stage this argument must be added manually, but we'll add an UI for that in the next stage.As you may have noticed users will have to go through Login Selector anyway, but the
Continue as Guest
option will be selected automatically. We do this to re-use lots of functionality we already implemented in the Login Selector to cover all possible fail cases when user cannot log in anonymously.Fixes: #18331
Release note: it will now be possible to log in to Kibana anonymously without using any 3rd-party reverse proxy workarounds.