Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions 0000-constrained-backends.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
- Feature Name: constrained backends
- Start Date: 2023-06-23
- SEP Status: Draft
- SEP PR: (leave this empty)
- Salt Issue: (leave this empty)

# Summary
[summary]: #summary

Apply constraints to individual backends to allow collaboration with "foreign" backends.

# Motivation
[motivation]: #motivation

Why are we doing this? What use cases does it support? What is the expected outcome?

This will open parts of the configuration for other developers (maybe in another department or even external) to modify, but without giving them root rights, even if the minion runs as root.
Currently the publisher_acl is only applied via the salt api - but if a state enters the salt master via a (git) backend, there is no constraint checking, allowing anyone that can change an backend to basically change almost everything, if not everything.
For example: This hinders to allow "foreign" git repositories to be used as backend without extensive merge approval process.

In the end, an application administrator could contribute states / functions / ... that are specific to a software and enable more complex orchestrations, without having a merge approver to know everything about every application to spot (unintentional or intentional) malicious changes and an expert keeps being an expert for just one/assigned scope/s, without the need to be trusted with everything.

# Design
[design]: #detailed-design

This is the bulk of the SEP. Explain the design in enough detail for somebody familiar
with the product to understand, and for somebody familiar with the internals to implement. It should include:

- Definition of any new terminology
- "foreign" backend: a backend that can be modified by other users than the salt master administrator.
- Examples of how the feature is used:
- Target minions on backends
Users able to change webserver.git aren't always the same users that should be able to modify backupservers.
- Apply these states constrained to be applied as user x.

Choose a reason for hiding this comment

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

How? Fork a minion process running as the target user to run it? Most stuff would break, such as communication with the master.

Copy link
Author

Choose a reason for hiding this comment

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

"Target minions on backends" would modify (enable / disable) overlays of the fileserver on the base of targeting - which is controlled by the master. It would allow to create a "view" on a environment. This is maybe a feature on its own.

The latter "Apply these states constrained to be applied as user x" is tricky . as it would have to postprocess the output of a renderer, to ensure something like "runas" is set.
As for communication: The minion would have to act as proxy/filter for the unprivileged subprocess.

- This and more could be accomplished by forcing a render pipeline, that acts as gateway that applies or filters wrapping the renderers with another renderer, that applies/filters parts. Or simply raise an exception to stop further processing of a configuration state.

Choose a reason for hiding this comment

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

Changing the rendering has no effect on the running of the rendered states.

Copy link
Author

Choose a reason for hiding this comment

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

As the runtime can only run what it was given, i'll try to limit the output of the runtime by limiting the input of it.

- Allow just a certain list of renderers.

Choose a reason for hiding this comment

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

How does this help? Every renderer can run arbitrary commands as root.

Copy link
Author

Choose a reason for hiding this comment

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

A wrapper can ensure that the input (the file from the file backend) and output of a rendering pipeline fits certain criteria. First scanning for arbitrary commands/functions/... in the state file and later checking for arbitrary commands/functions in the returned output.
Limiting the list of renderers should simply allow a salt administrator to concentrate on a limited set of features that should be allowed/denied/enforced - as you said every renderer can run arbitrary commands, but those can be issued with a particular format subset that a renderer can understand. I think, the py renderer would be excluded most of the time.

But you are correct for this, encapsulating a constrained renderer in a sandbox like environment would be favorable. Hence my suggestion to allow an salt administrator to sandbox the rendering within a renderer has only access to scoped data and limited acting room to have an effect on the host/minion.

- Some renderers (like py) might have more capabilities than others to try to circumvent pillar scopes.


```
gitfs_remotes:
- https://foo.com/main.git
- https://foo.com/webserver.git:
- target: web-group-a\*
- renderer-prepend: malware_scan
- renderer-append: force_user_x
- renderer-allow:
- jinja|yaml
- https://foo.com/webserver.git:
- target: web-group-b\*
- renderer-append: force_user_y
- renderer-allow:
- jinja|yaml
- py
- https://foo.com/backups.git:
- target: backup\*
```

The last part, is still unpolished:
* Render (some) state files in a sandbox.
* Rendering itself can be harmful on the salt master, as the renderer (for example: py) might get access to data / pillars that is not in scope for the targeted minion. Restricting the information that is available.

Choose a reason for hiding this comment

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

This isn't true. State rendering happens on the minion. There's no way to access other minions' pillars.

Copy link
Author

Choose a reason for hiding this comment

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

Sorry, my mixup. I corrected it.
Had originally in mind to call the minion a submaster of sorts.

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

Seems like Github is not updating this PR with the latest commits i've pushed to my fork's master.

Copy link
Author

Choose a reason for hiding this comment

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

Found a solution for githubs lack of PR updates: https://github.com/orgs/community/discussions/16351#discussioncomment-6327770 Sorry for the notification noise.

```
gitfs_remotes:
- https://foo.com/main.git
- https://foo.com/webserver.git:
- renderer-allow:
- py
- renderer-sandbox:
- ## TODO: syntax for passing scoped pillar data ##
```

- Outline of a test plan for this feature. How do you plan to test it? Can it be automated?
- Create multiple repositories and check if they had an effect on other minions than targeted.
- Create a state file for the py renderer and write data to the salt master. Check if data has been written (it should not).
- Create functions distributed over multiple repositories and use them together in an orchestrate runner.
- ...


## Alternatives
[alternatives]: #alternatives

What other designs have been considered?
* Running multiple minions and masters as non root in their respective contexts. But this hinders orchestration.

What is the impact of not doing this?
* Collaboration via different backends is not possible if anyone does not fit in the scope of salt master trustees.

## Unresolved questions
[unresolved]: #unresolved-questions

What parts of the design are still TBD?

Sandboxing of renderers.

# Drawbacks
[drawbacks]: #drawbacks

Why should we *not* do this? Please consider:

- Implementation cost, both in term of code size and complexity
- Sandboxing and scoping pillardata might have a higher complexity
- Integration of this feature with other existing and planned features
- no
- Cost of migrating existing Salt setups (is it a breaking change?)
- no
- Documentation (would Salt documentation need to be re-organized or altered?)
- no


There are tradeoffs to choosing any path. Attempt to identify them here.