-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
Move security tokens to a separate internal index #37236
Move security tokens to a separate internal index #37236
Conversation
Pinging @elastic/es-security |
@albertzaharovits can you clarify what part of this change is breaking? |
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 left some comments/questions after a quick review
@@ -0,0 +1,151 @@ | |||
{ |
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.
why is this a new file?
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 will be present in 6.7 only. When I backport to 7 new-security-index-template.json
will take the place of security-index-template.json
.
The rationale is as follows:
In 6.7 nodes will create .security-6
as usual, if the index is missing (fresh install).
_xpack/migration/upgrade/.security-6
should be called before rolling upgrading to 7.
The alternative could have been to create .security-7
on a fresh 6.7 install, but during a rolling upgrade from 6.6 to 6.7, 6.7 nodes might erroneously consider they have to create .security-7
.
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 will be present in 6.7 only. When I backport to 7
This phrasing confuses me a little - what I assume you mean is that once you've backported this change to 6.7 you will update master (7.0) to have only a single template (rename new-security-index-template.json
to security-index-template.json
).
I think in that case it might be better to name the json files as security-index-template-6.json
and security-index-template-7.json
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're right, will do!
@@ -0,0 +1,151 @@ | |||
{ | |||
"index_patterns" : [ ".security-*" ], |
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.
we should probably exclude the tokens index from getting this template
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.
We don't use these files as templates anymore, so the index_pattern
field is only for doc purposes only. I agree it is confusing, I will change it.
DeleteByQueryRequest expiredDbq = new DeleteByQueryRequest(SecurityIndexManager.SECURITY_INDEX_NAME); | ||
final DeleteByQueryRequest expiredDbq; | ||
if (securityTokensIndex.exists()) { | ||
expiredDbq = new DeleteByQueryRequest(securityTokensIndex.aliasName()); |
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.
is this truly a binary choice? Maybe the alias should point to both indices until the upgrade or something like 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.
It is a binary choice.
Tokens, expired or not, can sit in a single index at a certain moment in time: either .security-6
or .security-tokens-7
. When the remover job starts, it builds the query accordingly. It is possible that after building the query and before its execution, the tokens can move (from .security-6
to .security-tokens-7
) and the delete will miss them, but they will be catched by the next removal job.
@@ -217,6 +219,14 @@ public static Boolean isTokenServiceEnabled(Settings settings) { | |||
return XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.get(settings); | |||
} | |||
|
|||
private SecurityIndexManager indexManager() { | |||
if (securityTokensIndex.exists()) { |
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.
shouldn't we base this on the index format? also what about tokens created/invalidated while the upgrade is running
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.
shouldn't we base this on the index format?
I find that the alias existence (.security-tokens
) is enough to base the decision. Again, this is only a 6.7 thing, in 7 there is no decision to make, the token service will automatically generate its index.
what about tokens created/invalidated while the upgrade is running?
This is an important question!
During a time window during the upgrade, tokens will not be able to be created, refreshed or invalidated, but only to be used. These operations will fail. This is because .security-6
, which still has the tokens, is marked as read-only. I tried to minimize this time window. It is comprised of the reindex only of the token documents and the alias creation.
I thought that allowing writing to two indices while a reindex was going was too complicated. For example, the refresh/invalidation case would translate to an update on .security-6
and a create or update on .security-tokens-7
, and any of these two can theoretically fail independently. Maybe I don't know enough about versioning to come up with a plan about this...
I had an idea of storing the write token operations against .security-6
while the reindex is going on, and before the alias is shifted, in a bulk request and then replaying the bulk request on the first read against the new .security-tokens-7
index. Though, this is wrong in many aspects...
Do you think this is acceptable? Or do we need to find a solution to the read-only issue. I admit I was influenced by the upgrade method in 5.6, but there were no write intensive objects in .security
at that time.
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.
Alternatively, we can make sure that any write operations are retried.
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 think the read only aspect during the upgrade is definitely acceptable.
public static final String INTERNAL_SECURITY_INDEX = ".security-" + IndexUpgradeCheckVersion.UPRADE_VERSION; | ||
public static final int INTERNAL_INDEX_FORMAT = 6; | ||
public static final String SECURITY_ALIAS_NAME = ".security"; | ||
public static final int INTERNAL_SECURITY_INDEX_FORMAT = 6; |
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.
shouldn't we increment the version post upgrade?
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.
Yes, this is done in SecurityIndexUpgradeCheck#upgrade
. Again, this is the face of SecurityIndexManager
for 6.7 . In the 7 backport the number here will change to 7.
My reasoning was that the forking in itself is a breaking change, but it might not be... |
}, removeReadOnlyBlock)); | ||
}, removeReadOnlyBlock)); | ||
}, listener::onFailure)); | ||
}, listener::onFailure)); |
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.
@jaymode I think the upgrade method is a good place to deep dive in the PR review.
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 does not have tests, I know, I'll add them after a few review rounds.
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 think we also should go ahead and remove any documents with a type of invalidated-token
. These documents are really not relevant anymore
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.
Also this isn't available yet, but this might be a good place to make use of the StepListener
from #37327
Thank you @jaymode for the speedy review round, 'preciate 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.
@albertzaharovits thanks for the answers. I'm pretty happy with this approach. I think we should add tests and then I can review again.
@@ -217,6 +219,14 @@ public static Boolean isTokenServiceEnabled(Settings settings) { | |||
return XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.get(settings); | |||
} | |||
|
|||
private SecurityIndexManager indexManager() { | |||
if (securityTokensIndex.exists()) { |
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 think the read only aspect during the upgrade is definitely acceptable.
}, removeReadOnlyBlock)); | ||
}, removeReadOnlyBlock)); | ||
}, listener::onFailure)); | ||
}, listener::onFailure)); |
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 think we also should go ahead and remove any documents with a type of invalidated-token
. These documents are really not relevant anymore
}, removeReadOnlyBlock)); | ||
}, removeReadOnlyBlock)); | ||
}, listener::onFailure)); | ||
}, listener::onFailure)); |
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.
Also this isn't available yet, but this might be a good place to make use of the StepListener
from #37327
Hey all, I'm implementing the UI side of the Upgrade Assistant for 6.x -> 7.x. Since starting this project, we've been working under the assumption that no internal indices were going to need to be transformed/upgrade beyond a normal reindex that all 5.x indices would need. This change would introduce the first and only internal index upgrade for 7.x. With 2 weeks until FF for 6.7, I'm worried that adding in this functionality on the Kibana side of things is going to put the upgrade at risk of missing FF. We still have other things to complete on our side and a load of integration testing that needs to be done to ensure a smooth upgrade to 7.0 for customers. Without much context on this change, it seems that this may not be critical for 7.x. Are there customers who have large snapshots due to tokens being in the same index? If the only reason for doing this is to reduce snapshot sizes for the .security index and there aren't any customers with complaining about .security snapshot size, is it possible we could hold off on this change? Alternatively, I'm curious what the rationale is behind making this change require user intervention. Is it not possible to apply this transformation when Elasticsearch boots up? In Kibana 6.5, we added a similar migrations mechanism that performs index transformations when Kibana boots. Would it be possible to do something similar for this change in ES so no user intervention is required? |
This is indeed a nice to have. Access tokens take up space and time and are unusable after a restore (i.e. are expired or encrypted with a forgone key).
We can make the upgrade automatic in the background. I've been musing this as well. But we need to decide on a "trigger" for the upgrade. Plus, given the example in 5.6 I was under the impresion that the user intervention is the idiomatic way to do it. I can move tokens to the separate index without updating the mapping on the This PR is close, it only needs an integ test for the upgrade proc. I can work on it right know and be done with it soon. Thoughts @jaymode ? |
My understanding is that we did not want to have upgrades happen without user intervention; I think @s1monw had some specific concerns with the automatic upgrades.
If you want to get this ready, that's fine but it might be something we push off until 7.x for the upgrade from 7 to 8. |
Thanks for the context, it sounds like pushing may be our best option. As we're getting closer to FF, I'll have a better idea of whether or not we'll have enough time on the Kibana side to support this in the Upgrade Assistant. Ideally, I'd like to make it happen. I should know better by middle of next week as things start to wrap up. |
good catch @joshdover . Thanks for diligently watching other repos :) I agree that we should avoid building custom reindexing logic this late in the game. Since tokens are short lived, I wonder if there is an option to naturally let things move from one index to another - i.e., when a session is created it will always be create in the new index while session lookups will be done both in the new index and in the |
Thanks for digging into alternatives @bleskes ! We could do that. But this would be leaving the mappings for tokens lingering in the old Instead, I propose we keep the manual intervention for the upgrade and the dual format compatibility in 7.x releases. The dual format compatibility (tokens can be in any index but not in both) in this PR was originally targeted for 6.7 only, and now I suggest we retarget it to 7.x. This way no migration/upgrade is available/necessary in 6.7, and for the 7.x releases I believe this alternative achieves both the ease of the 6.7 - 7 upgrade and improves our story about snapshotting/restoring |
I think the way @bleskes proposes is similar to what we've done in 6.x with tokens. Pre-6.2 we only indexed invalidation docs; post 6.2 we indexed invalidation and the token doc. For 7.0+ we only store the token doc. Given the power of our search api, if the format of the docs stays the same we can search Ping @jkakavas for thoughts as he has done a good amount of work in this area recently. |
@albertzaharovits Should we close this PR now that we have #40742? |
No, this should be discontinued, thanks for the ping! |
This PR moves authn tokens out from
.security
into their own index. It also includes the upgrade procedure.The main reason for this change is that tokens are perishable. They should not be having the long lifetime of a password, as this is the shortcoming they were designed to alleviate in the first place. For that matter, they should usually not be included in backups because they would be wasting storage. In addition, restoring the
.security
on a live cluster will not hamper ongoing clients authn using tokens, because by default, the tokens index will not be restored/snapshoted.Concretely, after the update the following structure will be effected:
The upgrade procedure is designed to work on 6.7 . 6.7 nodes understand the previous format as well as the new format. All nodes should be on a version greater than 6.7 for the upgrade assistant to work (
_xpack/migration/upgrade/.security-6
).