-
Notifications
You must be signed in to change notification settings - Fork 82
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
invalidate remote api keys on unenroll #3154
Changes from 7 commits
3e06b0f
e2679f8
55803dc
2ec7678
88d1cb8
a6efc9b
35f3539
b183e55
853745b
26dd618
3585b69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -567,62 +567,16 @@ func cleanRoles(roles json.RawMessage) (json.RawMessage, int, error) { | |
} | ||
|
||
func (ack *AckT) invalidateAPIKeys(ctx context.Context, zlog zerolog.Logger, toRetireAPIKeyIDs []model.ToRetireAPIKeyIdsItems, skip string) { | ||
ids := make([]string, 0, len(toRetireAPIKeyIDs)) | ||
remoteIds := make(map[string][]string) | ||
for _, k := range toRetireAPIKeyIDs { | ||
if k.ID == skip || k.ID == "" { | ||
continue | ||
} | ||
if k.Output != "" { | ||
if remoteIds[k.Output] == nil { | ||
remoteIds[k.Output] = make([]string, 0) | ||
} | ||
remoteIds[k.Output] = append(remoteIds[k.Output], k.ID) | ||
} else { | ||
ids = append(ids, k.ID) | ||
} | ||
} | ||
if len(ids) > 0 { | ||
zlog.Info().Strs("fleet.policy.apiKeyIDsToRetire", ids).Msg("Invalidate old API keys") | ||
if err := ack.bulk.APIKeyInvalidate(ctx, ids...); err != nil { | ||
zlog.Info().Err(err).Strs("ids", ids).Msg("Failed to invalidate API keys") | ||
} | ||
} | ||
// using remote es bulker to invalidate api key | ||
for outputName, outputIds := range remoteIds { | ||
outputBulk := ack.bulk.GetBulker(outputName) | ||
|
||
if outputBulk == nil { | ||
// read output config from .fleet-policies, not filtering by policy id as agent could be reassigned | ||
policy, err := dl.QueryOutputFromPolicy(ctx, ack.bulk, outputName) | ||
if err != nil || policy == nil { | ||
zlog.Warn().Str("outputName", outputName).Any("ids", outputIds).Msg("Output policy not found, API keys will be orphaned") | ||
} else { | ||
outputBulk, _, err = ack.bulk.CreateAndGetBulker(ctx, zlog, outputName, policy.Data.Outputs) | ||
if err != nil { | ||
zlog.Warn().Str("outputName", outputName).Any("ids", outputIds).Msg("Failed to recreate output bulker, API keys will be orphaned") | ||
} | ||
} | ||
} | ||
if outputBulk != nil { | ||
if err := outputBulk.APIKeyInvalidate(ctx, outputIds...); err != nil { | ||
zlog.Info().Err(err).Strs("ids", outputIds).Str("outputName", outputName).Msg("Failed to invalidate API keys") | ||
} | ||
} | ||
} | ||
invalidateAPIKeys(ctx, zlog, ack.bulk, toRetireAPIKeyIDs, skip) | ||
} | ||
|
||
func (ack *AckT) handleUnenroll(ctx context.Context, zlog zerolog.Logger, agent *model.Agent) error { | ||
span, ctx := apm.StartSpan(ctx, "ackUnenroll", "process") | ||
defer span.End() | ||
apiKeys := agent.APIKeyIDs() | ||
if len(apiKeys) > 0 { | ||
zlog = zlog.With().Strs(LogAPIKeyID, apiKeys).Logger() | ||
|
||
if err := ack.bulk.APIKeyInvalidate(ctx, apiKeys...); err != nil { | ||
return fmt.Errorf("handleUnenroll invalidate apikey: %w", err) | ||
} | ||
} | ||
apiKeys := agent.APIKeyIDs() | ||
zlog.Info().Any("fleet.policy.apiKeyIDsToRetire", apiKeys).Msg("handleUnenroll invalidate API keys") | ||
ack.invalidateAPIKeys(ctx, zlog, apiKeys, "") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. building |
||
|
||
now := time.Now().UTC().Format(time.RFC3339) | ||
doc := bulk.UpdateFields{ | ||
|
@@ -740,3 +694,49 @@ func makeUpdatePolicyBody(policyID string, newRev, coordIdx int64) []byte { | |
|
||
return buf.Bytes() | ||
} | ||
|
||
func invalidateAPIKeys(ctx context.Context, zlog zerolog.Logger, bulk bulk.Bulk, toRetireAPIKeyIDs []model.ToRetireAPIKeyIdsItems, skip string) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. moved this function outside of |
||
ids := make([]string, 0, len(toRetireAPIKeyIDs)) | ||
remoteIds := make(map[string][]string) | ||
for _, k := range toRetireAPIKeyIDs { | ||
if k.ID == skip || k.ID == "" { | ||
continue | ||
} | ||
if k.Output != "" { | ||
if remoteIds[k.Output] == nil { | ||
remoteIds[k.Output] = make([]string, 0) | ||
} | ||
remoteIds[k.Output] = append(remoteIds[k.Output], k.ID) | ||
} else { | ||
ids = append(ids, k.ID) | ||
} | ||
} | ||
if len(ids) > 0 { | ||
zlog.Info().Strs("fleet.policy.apiKeyIDsToRetire", ids).Msg("Invalidate old API keys") | ||
if err := bulk.APIKeyInvalidate(ctx, ids...); err != nil { | ||
zlog.Info().Err(err).Strs("ids", ids).Msg("Failed to invalidate API keys") | ||
} | ||
} | ||
// using remote es bulker to invalidate api key | ||
for outputName, outputIds := range remoteIds { | ||
outputBulk := bulk.GetBulker(outputName) | ||
|
||
if outputBulk == nil { | ||
// read output config from .fleet-policies, not filtering by policy id as agent could be reassigned | ||
policy, err := dl.QueryOutputFromPolicy(ctx, bulk, outputName) | ||
if err != nil || policy == nil { | ||
zlog.Warn().Str("outputName", outputName).Any("ids", outputIds).Msg("Output policy not found, API keys will be orphaned") | ||
} else { | ||
outputBulk, _, err = bulk.CreateAndGetBulker(ctx, zlog, outputName, policy.Data.Outputs) | ||
if err != nil { | ||
zlog.Warn().Str("outputName", outputName).Any("ids", outputIds).Msg("Failed to recreate output bulker, API keys will be orphaned") | ||
} | ||
} | ||
} | ||
if outputBulk != nil { | ||
if err := outputBulk.APIKeyInvalidate(ctx, outputIds...); err != nil { | ||
zlog.Info().Err(err).Strs("ids", outputIds).Str("outputName", outputName).Msg("Failed to invalidate API keys") | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,6 +119,11 @@ | |
|
||
agent, err := authAgent(r, &id, ct.bulker, ct.cache) | ||
if err != nil { | ||
// invalidate remote API keys of force unenrolled agents | ||
if err == ErrAgentInactive && agent != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added testing steps of the force unenroll scenario to the pr description. Decided to invalidate remote API keys on checkin here, when finding that the agent is inactive, because the agent becomes inactive after force unenroll. It's not guaranteed that the agent is going to check-in after force unenroll, but we can't do the invalidation in kibana, as kibana doesn't have access to the remote es service token as it is a secret. |
||
ctx := zlog.WithContext(r.Context()) | ||
invalidateAPIKeysOfInactiveAgent(ctx, zlog, ct.bulker, agent) | ||
} | ||
return err | ||
} | ||
|
||
|
@@ -136,6 +141,18 @@ | |
return ct.ProcessRequest(zlog, w, r, start, agent, newVer) | ||
} | ||
|
||
func invalidateAPIKeysOfInactiveAgent(ctx context.Context, zlog zerolog.Logger, bulker bulk.Bulk, agent *model.Agent) { | ||
remoteAPIKeys := make([]model.ToRetireAPIKeyIdsItems, 0) | ||
apiKeys := agent.APIKeyIDs() | ||
for _, key := range apiKeys { | ||
if key.Output != "" { | ||
remoteAPIKeys = append(remoteAPIKeys, key) | ||
} | ||
} | ||
zlog.Info().Any("fleet.policy.apiKeyIDsToRetire", remoteAPIKeys).Msg("handleCheckin invalidate remote API keys") | ||
invalidateAPIKeys(ctx, zlog, bulker, remoteAPIKeys, "") | ||
} | ||
|
||
// validatedCheckin is a struct to wrap all the things that validateRequest returns. | ||
type validatedCheckin struct { | ||
req *CheckinRequest | ||
|
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 change broke the automation with updatecli, see https://github.com/elastic/fleet-server/actions/runs/7197121542
is that the expected behaviour?
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.
sorry, I changed it to fix e2e tests, it was not working with a specific 8.13 build
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.
how can we fix this?
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.
Using
8.13.0-jqmw70gd
inmain
and8.12.0-8db20ea5
in8.12
I took those values from https://github.com/elastic/fleet-server/actions/runs/7197121542/job/19603532844#step:3:213
https://storage.googleapis.com/artifacts-api/snapshots/8.12.json
https://storage.googleapis.com/artifacts-api/snapshots/main.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.
do you mind raising prs to fix this or do you want me to?