Skip to content

Enable unprivileged on macos#4362

Merged
pierrehilbert merged 18 commits intoelastic:mainfrom
pchila:enable-unprivileged-on-macos
Mar 14, 2024
Merged

Enable unprivileged on macos#4362
pierrehilbert merged 18 commits intoelastic:mainfrom
pchila:enable-unprivileged-on-macos

Conversation

@pchila
Copy link
Copy Markdown
Member

@pchila pchila commented Mar 5, 2024

What does this PR do?

This PR allows running elastic-agent (either installed or just extracted from the package) as an unprivileged user, using a file-based vault as fallback instead of the keychain-based one.

When creating an EncryptedDiskStore, we can specify an unprivileged flag which will instantiate the file-based vault on Mac OS (the default value of such flag is defined as whether elastic-agent is running with administrative rights).

In most cases, such default value is enough to choose the correct vault implementation: the exception is elastic-agent uninstall command where a specific check for a file vault containing the agent secret has been added.
The additional check during uninstall is necessary since the command needs to run with administrative rights for both privileged and unprivileged elastic-agent installs (a simple check of the user permissions would not be useful as we would always come up with privileged permissions)

Why is it important?

This change enables elastic-agent to be installed and run as an unprivileged user on Mac OS

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation
  • [ ] I have made corresponding change to the default configuration files
  • I have added tests that prove my fix is effective or that my feature works
  • I have added an entry in ./changelog/fragments using the changelog tool
  • [ ] I have added an integration test or an E2E test

Author's Checklist

  • [ ]

How to test this PR locally

Related issues

Use cases

Screenshots

Logs

Questions to ask yourself

  • How are we going to support this in production?
  • How are we going to measure its adoption?
  • How are we going to debug this?
  • What are the metrics I should take care of?
  • ...

@pchila pchila added enhancement New feature or request Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team Team:Elastic-Agent Label for the Agent team labels Mar 5, 2024
@pchila pchila self-assigned this Mar 5, 2024
@pchila pchila force-pushed the enable-unprivileged-on-macos branch from 3a4bd8c to 29e64a8 Compare March 5, 2024 20:16
@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 5, 2024

This pull request does not have a backport label. Could you fix it @pchila? 🙏
To fixup this pull request, you need to add the backport labels for the needed
branches, such as:

  • backport-v./d./d./d is the label to automatically backport to the 8./d branch. /d is the digit

NOTE: backport-skip has been added to this pull request.

@mergify mergify bot added the backport-skip label Mar 5, 2024
@pchila pchila force-pushed the enable-unprivileged-on-macos branch 2 times, most recently from 980f9f8 to e5d7ea9 Compare March 11, 2024 14:14
@pchila pchila requested a review from blakerouse March 11, 2024 14:15
@pchila pchila marked this pull request as ready for review March 11, 2024 14:15
@pchila pchila requested a review from a team as a code owner March 11, 2024 14:15
@pchila pchila requested a review from leehinman March 11, 2024 14:15
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/elastic-agent-control-plane (Team:Elastic-Agent-Control-Plane)

// Deprecated: MacOS can be run/installed without root privileges
cmd.Flags().Bool("disable-encrypted-store", false, "Disable the encrypted disk storage (Only useful on Mac OS)")
_ = cmd.Flags().MarkHidden("disable-encrypted-store")
_ = cmd.Flags().MarkDeprecated("disable-encrypted-store", "agent on Mac OS can be run/installed without root privileges, see elastic-agent install --help")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

// try early to check if running as root
isRoot, err := utils.HasRoot()
if err != nil {
return fmt.Errorf("failed to check for root permissions: %w", err)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The others you added used the word administrator and this one used root. I believe that was just because this was moved. I would like to see this consitent, maybe root/Administrator would be better and work for unix and windows.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleaned up a bit in b508570


hasRoot, err := utils.HasRoot()
if err != nil || !hasRoot {
// TODO log error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cmacknz
Copy link
Copy Markdown
Member

cmacknz commented Mar 11, 2024

We don't have a MacOS runner for integration tests yet. What is the plan for ensuring this works with the same level of confidence as Windows and Linux? We have a manual QA team that can help verify this, but we'd have to provide a detailed list of test cases first.

@pchila
Copy link
Copy Markdown
Member Author

pchila commented Mar 11, 2024

We don't have a MacOS runner for integration tests yet. What is the plan for ensuring this works with the same level of confidence as Windows and Linux? We have a manual QA team that can help verify this, but we'd have to provide a detailed list of test cases first.

Not sure what other testcases may come to mind but here's what I have tested:

  1. elastic-agent run from an uncompressed elastic-agent package as a regular Mac user
  2. sudo elastic-agent install --unprivileged for standalone mode and fleet managed

Aside from checking manually that privileged still works I cannot think of specific additional scenarios to test.
Maybe we can add a testcase with endpoint to verify that it doesn't run unless we install agent as privileged?

We have a real problem with automated testing for this kind of changes, unit tests are unfeasible without massive refactoring in the touched parts of code (I would like to avoid a big-bang scenario) and we don't have runners for integration tests on Mac as you pointed out.

@pchila pchila force-pushed the enable-unprivileged-on-macos branch from 87b84e7 to b508570 Compare March 12, 2024 13:30
@pchila pchila requested a review from blakerouse March 12, 2024 13:31
Copy link
Copy Markdown
Contributor

@blakerouse blakerouse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Thanks for adding tests where you could, a lot of these areas are really hard to unit tests.

@cmacknz
Copy link
Copy Markdown
Member

cmacknz commented Mar 12, 2024

Not sure what other testcases may come to mind but here's what I have tested:

  1. elastic-agent run from an uncompressed elastic-agent package as a regular Mac user
  2. sudo elastic-agent install --unprivileged for standalone mode and fleet managed

Do upgrades work?

We have a real problem with automated testing for this kind of changes, unit tests are unfeasible without massive refactoring in the touched parts of code (I would like to avoid a big-bang scenario) and we don't have runners for integration tests on Mac as you pointed out.

Long term the answer is to add a MacOS integration test runner, I don't expect this to be covered purely with unit tests.

pchila added 8 commits March 13, 2024 07:28
Checking if we are running as root when creating the EncryptedDiskStore
removes the need for propagating an unprivileged flag from a lot of
places in the code.
Only exception is the uninstall command, since it needs to run with
administrator privileges: in there we check for existence of a FileVault
containing the agent secret to detect if we have to load the agent
configuration as unprivileged (currently relevant only on Darwin)
@pchila pchila force-pushed the enable-unprivileged-on-macos branch from b508570 to 795bbbe Compare March 13, 2024 06:28
@elastic-sonarqube
Copy link
Copy Markdown

Quality Gate failed Quality Gate failed

Failed conditions

33.3% 33.3% Coverage on New Code (required ≥ 40%)

See analysis details on SonarQube

@pchila
Copy link
Copy Markdown
Member Author

pchila commented Mar 13, 2024

Do upgrades work?

@cmacknz I just tested by repackaging the agent (we cannot downgrade as the old agent versions do not support running unprivileged) and everything works as expected when launching the upgrade with sudo -u elastic-agent elastic-agent upgrade ... so at least that still works

@pierrehilbert
Copy link
Copy Markdown
Contributor

Long term the answer is to add a MacOS integration test runner, I don't expect this to be covered purely with unit tests.

cc @rowlandgeoff to ensure this is under your radar.

@pierrehilbert
Copy link
Copy Markdown
Contributor

As discussed in our weekly meeting, this PR contains what is possible to be tested until we have our MacOS runner so I'm force merging even if SonarQube is not happy with the coverage level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-skip enhancement New feature or request Team:Elastic-Agent Label for the Agent team Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Unprivileged] Enable --unprivileged on macOS

5 participants