jpoehnelt / secrets-sync-action

A Github Action that can sync secrets from one repository to many others.
https://github.com/marketplace/actions/secrets-sync-action
Apache License 2.0
314 stars 92 forks source link

feature: sync secrets to Azure DevOps instances #92

Closed SvenStaehs closed 1 year ago

SvenStaehs commented 1 year ago

Hi, I have a feature suggestion:
I'd love to use this action to sync not only our GitHub Enterprise projects, but also to variable groups in Azure DevOps instances (both Server and Service/Cloud). There is a REST API to update variable groups, but I haven't tested it yet. Have you thought about this already? Here are my thoughts:

  1. GitHub secrets would need to be mapped to variables in variable groups in some way, maybe you'd run the action once for every variable group to sync into: give both the DevOps Organisation URL and variable group ID as inputs, the GITHUB_TOKEN would have to be a DevOps token of course, maybe refactor its name to "ACCESS_TOKEN" 😉. This "one action for each variable group" idea makes extra sense considering each group may have a different maintainer, so a different access token may be required for some groups.

  2. I'm worried that the REST API may not allow to sync single secrets and it will simply delete any variables that aren't in the payload (there doesn't seem to be any other way to delete variables via REST).
    If so, we have to mention this as a big warning in the readme, potentially we could introduce a safeguard: Before actually synching, get the current content of the group and check it against what we are about to send. Abort with error message if there are variables we aren't going to set. Possibly allow to disable this check with an "allowDeletingExisting: true" input variable or something...
    We could read the value of non-secret variables and simply reset them to the existing value, so we would only need to fail if there are secrets we can't update (you don't get their value via REST), but special treatment like this makes the whole thing more complicated and edge cases hard to understand, so better to keep it simple.

  3. People would want to specify the "group name" as input instead of "group ID", we can use a REST endpoint to get the group ID from the name, I think we should do this for the user.

  4. DevOps has the concept of descriptions for variable groups. My hope is that if we don't specify one in the UPDATE call, it will just keep the existing description. If this turns out not to be the case, we could require this as input to the action, potentially defaulting to "synchronized from GitHub repository https://..." and just overwriting any changes anyone may have done to the description in DevOps.
    As with the variables we could of course first check that nobody has modified it and fail if that's the case. It looks more and more like we will want to consider synced variable groups to be read-only on DevOps side and nobody should modify any aspect of them.

  5. Variable Groups have a couple other settings as well, like access permissions and whether it's automatically accessible from every pipeline... I'm not sure we should create variable groups that don't exist. If we did, we would have to mirror all these settings in inputs for the action.
    Instead I suggest to require someone to manually set up the empty variable group to ensure they've set everything up correctly, and this action only updates existing groups. Encountering a non-existent group would be treated as error.

  6. DevOps has the concept of non-secret variables that are automatically available to actions as environment variables, but I think we should ignore this and actively set everything we sync to "isSecret".
    Otherwise we would have to specify for each variable whether it should be a secret or not... Or can you easily set this on the patterns, like this?

    - secrets:
     - pattern: "^FOO_"
     - pattern: "^BAR_"
       isSecret: false # default is true

    This will require some refactoring of the secrets input, but I believe we can keep the old syntax working in parallel to the proposed one (I've seen the same handled elsewhere, I myself have no idea how yaml parsing works 😜) Otherwise have some naming convention like "if the secret name starts with 'NONSECRET_', remove this prefix from the variable name to be synched and set 'isSecret: false'". But I don't like to do stuff like that. Whatever the case, this is an optional feature and the initial implementation shouldn't support this at all to keep it simple 😉

Please let me know what you think.

jpoehnelt commented 1 year ago

Seems out of scope for this GitHub action. Feel free to fork.