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

[Fleet] Secrets are visible after saving package policy #178004

Closed
kpollich opened this issue Mar 5, 2024 · 7 comments · Fixed by #178045
Closed

[Fleet] Secrets are visible after saving package policy #178004

kpollich opened this issue Mar 5, 2024 · 7 comments · Fixed by #178045
Assignees
Labels
Team:Fleet Team label for Observability Data Collection Fleet team

Comments

@kpollich
Copy link
Member

kpollich commented Mar 5, 2024

After creating a package policy for the AWS S3 policy template, secret values can be retrieved via the replace button in the secret field UI.

The secret values are also stored in plaintext on the resulting package policy saved object - this is the root of the issue.

Steps to reproduce

  1. Create package policy for AWS S3 integration (policy template)
  2. Fill in secrets for access key id, secret access key, session token
  3. Save policy
  4. Edit newly-created policy
  5. Observe that clicking "replace secret" button on each secret variable allows user to see the secret in plaintext
  6. Observe that the package policy saved object contains a value for each of these secrets as well, e.g.
"vars": {
  "shared_credential_file": {
    "type": "text"
  },
  "credential_profile_name": {
    "type": "text"
  },
  "access_key_id": {
    "type": "password",
    "value": "123123123"
  },
  "secret_access_key": {
    "type": "password",
    "value": "123123123"
  },
  "session_token": {
    "type": "password",
    "value": "123123123"
  },
  "role_arn": {
    "type": "text"
  },
  "default_region": {
    "value": "",
    "type": "text"
  },
  "proxy_url": {
    "type": "text"
  }
}

Screen recording

Screen.Recording.2024-03-05.at.8.53.06.AM.mov
@kpollich kpollich added the Team:Fleet Team label for Observability Data Collection Fleet team label Mar 5, 2024
@kpollich kpollich self-assigned this Mar 5, 2024
@elasticmachine
Copy link
Contributor

Pinging @elastic/fleet (Team:Fleet)

@kpollich
Copy link
Member Author

kpollich commented Mar 5, 2024

This is affecting all secrets, not just package level secrets.

@kpollich
Copy link
Member Author

kpollich commented Mar 5, 2024

I received this as a bug report in Slack, but I think what might be going on is the user doesn't have Fleet Server running, so secrets storage is force-disabled by Fleet.

I wonder if we should loosen this behavior, as a user could boot up Fleet Server at any time to begin decoding secrets. @elastic/fleet any thoughts?

@kpollich
Copy link
Member Author

kpollich commented Mar 5, 2024

Also, we probably shouldn't show the secrets editor UI components when secrets storage is disabled.

@kpollich
Copy link
Member Author

kpollich commented Mar 5, 2024

I took some time to test secrets across multiple stack upgrades to simulate a long running deployment to see if I could shake any issues loose related to this. See my steps + observations below:

  1. Created a cluster on 8.9.2
  2. Created a package policy for AWS S3 on the aws-2.9.1 integration

Pasted image 20240305122537

Pasted image 20240305122740

  1. Upgrade cluster to 8.10.4. Note new AWS version is available

image

  1. Upgrade integration + policies. Note no secrets in use quite yet

image

  1. Upgrade cluster to 8.11.2. Observe new version of AWS is available again

image

  1. Upgrade without also upgrading policies this time, just to verify what the state of once secrets are supported

  2. Observe Upgrade button is available on integration policies table

image

  1. Observe secrets onboarding callout is displayed

image

  1. Can view secrets via "replace" button in UI

image

  1. Save policy, observe that secrets can be still be revealed

image

  1. Observe secret values still exist in plaintext on the policy saved object, e.g.
GET kbn:/api/fleet/package_policies/bc0eec6d-3067-4695-beb8-5d4ffe9a3ab4
"vars": {
    "shared_credential_file": {
      "type": "text"
    },
    "credential_profile_name": {
      "type": "text"
    },
    "access_key_id": {
      "type": "text",
      "value": "123_a"
    },
    "secret_access_key": {
      "type": "text",
      "value": "456_b"
    },
    "session_token": {
      "type": "text",
      "value": "789_c"
    },
    "role_arn": {
      "type": "text"
    },
    "default_region": {
      "value": "",
      "type": "text"
    },
    "proxy_url": {
      "type": "text"
    }
  },

One potential reason for the issue: secrets storage isn't actually enabled on my cluster because there's still an 8.9.2 Fleet Server enrolled, it's just offline:

image

I don't think our logic for enabling secrets storage accounts for offline Fleet Servers, e.g.

export async function isSecretStorageEnabled(
esClient: ElasticsearchClient,
soClient: SavedObjectsClientContract
): Promise<boolean> {
const logger = appContextService.getLogger();
// first check if the feature flag is enabled, if not secrets are disabled
const { secretsStorage: secretsStorageEnabled } = appContextService.getExperimentalFeatures();
if (!secretsStorageEnabled) {
logger.debug('Secrets storage is disabled by feature flag');
return false;
}
// if serverless then secrets will always be supported
const isFleetServerStandalone =
appContextService.getConfig()?.internal?.fleetServerStandalone ?? false;
if (isFleetServerStandalone) {
logger.trace('Secrets storage is enabled as fleet server is standalone');
return true;
}
// now check the flag in settings to see if the fleet server requirement has already been met
// once the requirement has been met, secrets are always on
const settings = await settingsService.getSettingsOrUndefined(soClient);
if (settings && settings.secret_storage_requirements_met) {
logger.debug('Secrets storage requirements already met, turned on in settings');
return true;
}
// otherwise check if we have the minimum fleet server version and enable secrets if so
if (
await allFleetServerVersionsAreAtLeast(esClient, soClient, SECRETS_MINIMUM_FLEET_SERVER_VERSION)
) {
logger.debug('Enabling secrets storage as minimum fleet server version has been met');
try {
await settingsService.saveSettings(soClient, {
secret_storage_requirements_met: true,
});
} catch (err) {
// we can suppress this error as it will be retried on the next function call
logger.warn(`Failed to save settings after enabling secrets storage: ${err.message}`);
}
return true;
}
logger.info('Secrets storage is disabled as minimum fleet server version has not been met');
return false;
}

Pulling the cluster logs for my Kibana instance I can see that secrets storage is indeed disabled:

image

So, this is actually working as expected today - we won't store secrets unless all detected Fleet Servers are on 8.10.0 or greater. We should probably make two improvements in the short term:

  1. Update the UI so we don't display secrets elements when secrets storage is disabled on the backend (in progress)
  2. Fix the Fleet Server check to assert that as long as one Fleet Server exists above 8.10.0 then secrets can be enabled

I'm working on a PR to fix the UI elements so we don't show various secrets form elements when secrets storage is actually not enabled on the backend by this implicit check.

Longer term, should we even keep the Fleet Server version -> secrets enabled/disabled gate in place? It seems to just add confusion and implicitness. What are the risks of removing it?

@jillguyonnet
Copy link
Contributor

Thanks for the detailed analysis report! I have a couple of questions around the Fleet Server related criteria to enable secrets.

Fix the Fleet Server check to assert that as long as one Fleet Server exists above 8.10.0 then secrets can be enabled

Longer term, should we even keep the Fleet Server version -> secrets enabled/disabled gate in place? It seems to just add confusion and implicitness. What are the risks of removing it?

If there is one Fleet Server on a version lower than 8.10.0, could there be a risk of breaking associated policies if secrets are enabled? AFAIK there is no granularity to secrets enabling.

I received this as a bug report in Slack, but I think what might be going on is the user doesn't have Fleet Server running, so secrets storage is force-disabled by Fleet.

I wonder if we should loosen this behavior, as a user could boot up Fleet Server at any time to begin decoding secrets. @elastic/fleet any thoughts?

Pretty much same question: if the user then adds a Fleet Server on a version lower than 8.10.0, could it break their policies?

Linking the original issue for reference: #157456

@juliaElastic
Copy link
Contributor

Pretty much same question: if the user then adds a Fleet Server on a version lower than 8.10.0, could it break their policies?

I think we might want to optimise for the most common use case: if a user start using a newest version of kibana, it is likely that they will use a newest version of fleet-server with it.
So I would lean to enable secrets if there are no fleet-servers, and add a warning that enrolling an older fleet-server would not work - possibly with a way to disable secrets with a button / automatically if someone really wants to use an old fleet-server version.

kpollich added a commit that referenced this issue Apr 12, 2024
Closes #178004

## Summary

Disables secrets UI inputs in forms when secrets storage is disabled
server-side. Previously, the server side check wasn't exposed to the
frontend in any way, so the behavior of detecting whether secrets were
enabled or not differed: the frontend wasn't aware when secrets were
disabled due to a missing Fleet Server of the proper version.

I've also added a UI callout when secrets are disabled due to the
failing Fleet Server version check:


![image](https://github.com/elastic/kibana/assets/6766512/c2c31f65-9579-4433-9fd5-7554995a51c1)

Lastly, I've updated the check for compatible Fleet Server versions to
ensure that only agents with `active: true` are included in the check.
Because we didn't have this check before, cloud clusters where the
previous agent running on the `Elastic Agent on Cloud` managed policy
appeared as `offline` or `unenrolled` would never be able to have
secrets enabled. I'd be open to narrowing this to a status check
instead, if there are concerns about this approach.

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Julia Bardi <90178898+juliaElastic@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team:Fleet Team label for Observability Data Collection Fleet team
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants