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

System vs User file/directory precedence #203

Closed
gokarnm opened this issue Jun 15, 2022 · 22 comments · Fixed by #445 or notaryproject/notation-go#179
Closed

System vs User file/directory precedence #203

gokarnm opened this issue Jun 15, 2022 · 22 comments · Fixed by #445 or notaryproject/notation-go#179
Assignees
Labels
spec Specifications to define the product requirements
Milestone

Comments

@gokarnm
Copy link
Contributor

gokarnm commented Jun 15, 2022

The directory structure spec defines system and user level directory paths. When both paths are present, it may be required to give precedence to system or user level based on specific scenarios.

  • User level setting in config.json and signingkeys.json may take precedence over system level settings in development scenarios, or an environment shared by multiple users.
  • In deployment scenarios, it may be desirable to use system level trustpolicy.json and trust store, even if an user level (application or service role) trust store and policy exists, to allow administrator roles to enforce usage of trust policy and store.

We should come up with an approach that is flexible to support both scenarios.

@gokarnm gokarnm changed the title System vs User directory precedence System vs User file/directory precedence Jun 15, 2022
@iamsamirzon
Copy link
Contributor

@gokarnm thinks we can start directory spec implementation while working in parallel to close this. This is not a blocker to start.

@gokarnm
Copy link
Contributor Author

gokarnm commented Jun 17, 2022

Here is a proposal for how to address this.

  1. Only in the system level config.json we provide a new setting configurationBehavior with supported values user/system which allows a system admin role to setup preferred configuration priority, which cannot be overriden by a user role. This setting applies to all files/directories (config.json, signingkeys.json, plugin dir, trustpolicy.json, trust store dir etc.)
  2. The default value of this setting if unspecified is user, so default behavior is user level files/directories take precedence over system level if both are present.

system - only system level settings are applied, user level settings are ignored in all cases, even when a specific setting is missing at system level and present at user level.
user - user level files/directories take precedence over system level if both are present.

Thoughts? @shizhMSFT @SteveLasker @priteshbandi @rgnote

@iamsamirzon
Copy link
Contributor

As per @gokarnm , this is not a blocker to start implementation.

@dtzar dtzar added this to the RC-1 milestone Jun 29, 2022
@dtzar
Copy link
Contributor

dtzar commented Jun 29, 2022

Related to #175 and #167

@dtzar
Copy link
Contributor

dtzar commented Jun 29, 2022

@junjie

@JeyJeyGao
Copy link
Contributor

I will add a comment to the related code to mention that the implementation may be changed later.

@SteveLasker
Copy link
Contributor

Thanks for capturing this @gokarnm
Balancing usability and security, this is one of those places where I'd suggest we need to lean a bit more to the security side, with a "secure by default" posture. If we leave the default to be user overrides, then we must assume most deployments will allow users to change the behavior, including default configurations of system configurations, where we are most exposed to "hacking".

What I'd suggest is we default system and force users to change to user if they really need it.

@SteveLasker
Copy link
Contributor

SteveLasker commented Jul 5, 2022

Who owns the action item to update the Directory Structure Specification? Is this assigned to @shizhMSFT? Thinking @dtzar, @FeynmanZhou, @iamsamirzon might be able to clarify the security/usability a bit first?

@shizhMSFT
Copy link
Contributor

@SteveLasker This is a discussion. We don't have a consensus yet. My opinion is that user file / directory should take over the system ones.

@dtzar
Copy link
Contributor

dtzar commented Jul 6, 2022

I'm assuming that the system-level directory is a security mechanism for certain things (like the trust store). Therefore, if the user directory overrides the system, wouldn't that be a security concern?

I can see a case for non-security implication changes it making sense to have the user directory override the system (i.e. configuration settings).

Maybe we could create a setting so someone concerned about security implications and wants to lock down to ignore user directory could do?

@SteveLasker
Copy link
Contributor

Thanks @shizhMSFT, @dtzar
David is capturing the heart of the issue. What is the proper "secure by default", starting point? Then, what could someone with admin privileges change, to enable a user to override, but only if configured.

For non-security related preferences, user overrides makes sense.

@dtzar dtzar added the spec Specifications to define the product requirements label Jul 11, 2022
@priteshbandi
Copy link
Contributor

priteshbandi commented Oct 7, 2022

Having different defaults for different configurations will be confusing and cumbersome for customers/users.

I think a setting like configuration-behavior with the default of user makes sense to avoid mis-configuration. If user creds are compromised a malicious actor can replace the notation invocation with the invocation to the dummy executable rendering our config protection useless.
Also, usually, the deployment host will be run as a user(not root) and if the user is compromised all bets are off. Is there any specific attack vector we are trying to defend?


Other option is to not allow user to have a config for at both system and user level. Basically, fail the operation(sign/verify) if user has defined config at both system and user level.

@dtzar
Copy link
Contributor

dtzar commented Oct 11, 2022

@yizha1 yizha1 assigned JeyJeyGao and unassigned shizhMSFT Oct 13, 2022
@JeyJeyGao
Copy link
Contributor

According to our meeting discussion, we can provide a system level /etc/notation/config.json file which contains an attribute EnableUserLevelDirectory with default value true, representing reading from user level directory firstly then reading system level directory. If it is false, only read from system level. This design requires system level read permission.
@shizhMSFT @yizha1 @FeynmanZhou @patrickzheng200

@SteveLasker
Copy link
Contributor

A secure by default scenario would suggest system is the default and the user must have admin privileges to enable the less secure user config.
As a security tool, seems we really need to start with a secure by default position to avoid the ease for a bad actor to make insecure changes.

@dtzar
Copy link
Contributor

dtzar commented Oct 13, 2022

Key decisions here as I see it:

  1. Do we even allow a configuration in two places (i.e. user and system)?
  2. If yes to 1 then do we allow anything in both places or just the non-security-specific configuration? What is deemed config versus security specifically?
  3. If yes to 1 then how do we handle which trumps the other in priority?

If no to 1, then we don't need to discuss 2 and 3.

@shizhMSFT
Copy link
Contributor

shizhMSFT commented Oct 14, 2022

We have identified at least three parties involved in the E2E scenarios: Signer, Verifier, and System Admin.

  • A Signer SHOULD be able to sign even if there is no system configuration. Here an example scenario:
    1. Alice downloads the notation CLI binary and corresponding signing plugins, and installs them without root access.
    2. Alice adds her signing keys using notation key add.
    3. After notation login, Alice is able to do notation sign to sign any artifact.
  • A Verifier SHOULD be able to verify artifacts securely. Since the notation CLI does not come with a default trust store and a default trust policy, the notation verify will always fail. The Verifier or the System Admin have to configure the notation with proper trust stores and policies based on different scenarios.
    • Scenario 1: Personal computers. Instances: Personal desktops, laptops, macs, etc.
      1. Bob downloads the notation CLI binary and installs it without root access.
      2. Bob downloads certificates, inspects them, and trusts them accordingly by notation cert add.
      3. Bob configures trust policies using notation policy (implemented in the dev-rc.1 branch).
      4. Bob verifies artifacts using notation verify and downloads the artifacts securely.
    • Scenario 2: Muti-tenant servers. Instances: University servers shared by students, etc.
      1. Bob downloads the notation CLI binary and installs it without root access if his university system admin has not pre-installed the notation CLI binary for all students yet.
      2. Bob downloads certificates, inspects them, and trusts them accordingly by notation cert add.
      3. Bob configures trust policies using notation policy (implemented in the dev-rc.1 branch).
      4. Bob verifies artifacts using notation verify and downloads the artifacts securely.
      5. Another student Charlie can do the steps b - d as Bob but using a different trust store / trust policy set.
    • Scenario 3: Dedicated servers. Instances: CI/CD machines, production servers, etc.
      1. David, as a System Admin, installs the notation CLI binary and configures config file / trust store / trust policy at the system level.
      2. Applications on the server verify artifacts using notation verify, download, and use the artifacts securely.
      3. Applications are NOT allowed to use their own trust store and trust policy. It follows the principle of least privilege.

To cover all above scenarios with maximum compatibility, one approach is to introduce a harden field (default to false) in the system level config file. When the notation process starts up, it checks if system level config file exists. If exists and harden is set to true, all trust store / trust policy / plugins paths MUST only use system level paths.

@SteveLasker
Copy link
Contributor

Thanks @shizhMSFT, @dtzar
The thing I’m most concerned with is a build redirecting the signing or verification to bypass the intended secure scenario.
Can we say:
If the notation cli is installed in the root, it must be configured with root access? This would enable the other scenarios when a needs local control

@shizhMSFT
Copy link
Contributor

Thanks @shizhMSFT, @dtzar The thing I’m most concerned with is a build redirecting the signing or verification to bypass the intended secure scenario. Can we say: If the notation cli is installed in the root, it must be configured with root access? This would enable the other scenarios when a needs local control

It is not possible check if the notation cli is installed in the root since you can install multiple instances of notation anywhere.

@SteveLasker
Copy link
Contributor

The goal is to avoid a bad actor to override a system configuration.
If the admin scenario is configured, wouldn’t there be a config, or trust store/policy in an admin path?
Can we check for the existence of that admin/root configuration and only allow that to be overridden if the root level config to enable user override is set?

@priteshbandi
Copy link
Contributor

priteshbandi commented Oct 17, 2022

From security perspective
Scenario 1 - works with user specific policy
Scenario 2: works with user specific policy
Scenario 3: - Can this work with specific user policy? usually dedicated server will run as a specific user, can notation use that user's role?

From usability perspective
Having an organization specific trust store that's distributed to all the hosts is one scenario where a system level trust store(TS) would be useful. Users can have both organization-specific ts and personal TS, notation will do a union of both the TS.

@priteshbandi
Copy link
Contributor

priteshbandi commented Oct 18, 2022

As per discussion in Notary v2 meeting on 10/17 for RC1 we will only support user level config and punt system level config for RC2.
Reason: We don't have a usecase where customer would like to use system level config and we can always add system level support later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec Specifications to define the product requirements
Projects
Status: Done
7 participants