policy-bot icon indicating copy to clipboard operation
policy-bot copied to clipboard

[Question]: Prevent changes to policy

Open shresthaujjwal opened this issue 2 years ago • 7 comments

As an enterprise, we would like to use same policy for everyone. In order to do that we would need to centralize the policy.yml configuration, which i can see its possible to do it by pointing the policy to remote repo. But its possible to override that by adding policy.yml in the repo. Is there a way to prevent this, can we add some type of flag or setting that would prevent overriding policy that is defined in one central place?

shresthaujjwal avatar Feb 01 '22 22:02 shresthaujjwal

There are two ways I can think of to achieve this, provided people cannot push directly to target branches:

  1. Disapprove any PRs that modify the policy file:

    policy:
      disapproval:
        if:
          changed_files:
            paths: [".policy.yml"] # replace with actual policy path
    

    This should post a failed status check on any PR that modifies the policy file. As long as the check is required, this will block PR merges.

  2. Require approval conditions for policy changes that can't be (realistically) satisfied:

    policy:
      approval:
        - policy changes are not allowed
    
    approval_rules:
      - name: policy changes are not allowed
        if:
          changed_files:
            paths: [".policy.yml"] # replace with actual policy path
        requires:
          count: 999 # some really high count that couldn't happen, or...
          users: ["service-account"] # the name of a user that doesn't exist or a service account for emergencies
    

I'd probably try option (1) first, since the red failed status should make it more obvious what is wrong. But option (2) could be valuable, especially if you want to make sure that policy changes require special approval, but could still happen if necessary.

Unfortunately, Policy Bot currently has no option to enforce a single configuration or prevent overrides at the server level, but that might be something we could add.

bluekeyes avatar Feb 01 '22 22:02 bluekeyes

Thank you @bluekeyes for prompt response. My choice would be option 3. If we have a configurable option to use a server side policy configuration then we don't even need to push our policy.yml file to users repo. It makes it very simple for all the developers, everyone will be enforced with same policy everywhere without any change to their repo.

shresthaujjwal avatar Feb 02 '22 05:02 shresthaujjwal

@bluekeyes it looks like bulldozer has the concept of global configuration https://github.com/palantir/bulldozer#configuration

You can also define a global default configuration when running your own instance of the server. This is used if the repository or the shared organization repository do not define any configuration.

Probably similar concept like this but with a flag in server side to prevent override from user's repo.

shresthaujjwal avatar Feb 02 '22 14:02 shresthaujjwal

@bluekeyes we are planning on enhancing this project with this feature if can point us to right direction that would be great, we will contribute it back once

shresthaujjwal avatar Feb 10 '22 21:02 shresthaujjwal

Here's a rough outline of how I think this would work:

  1. Add a DefaultPolicy field of type *policy.Config to handler.PullEvaluationOptions
  2. Add a new option, maybe IgnoreRepositoryPolicies or ForceServerPolicy to handler.PullEvaluationOptions. The important thing is to make the default value of false retain the current behavior.
  3. Modify handler.ConfigFetcher to take in the new properties and return the correct values from ConfigForPR. As you pointed out, Bulldozer has a similar implementation you could use a reference.

For the final feature, we'd probably want to also validate that if the "force server configuration" flag is set, then the default configuration is non-nil.

bluekeyes avatar Feb 10 '22 22:02 bluekeyes

thanks @bluekeyes . Will look into this. We will probably need to add similar flag in bulldozer project as well, it already has the global configuration concept just need to add the flag to prevent override. Will be addressing that too. If you have a design recommendation for bulldozer app, let me know I will open another issue in that repo

shresthaujjwal avatar Feb 11 '22 16:02 shresthaujjwal

This feature sounds nice, we're currently running a separate audit type script checking to ensure no one has added a .policy.yml file to their repo. Although not ideal, we had to loop through all the repos anyway to ensure no one removes the branch protection setting enforcement also so it wasn't all that bad to implement.

There are a few exceptions however, like we might want to enforce a remote policy on some repos and just use the default on others so we modified our audit script to just sure there's no .policy.yml with a policy key overriding the default config or the remote config and that seemed to be enough.

I think if there was a new option implemented, it could have several operating modes for flexibility, one of which could ignore policy files in the repo entirely, another that would just ignore policy files that define new policies and allow remote repo configs to be parsed fully.

devinburnette avatar Aug 16 '22 00:08 devinburnette