-
Notifications
You must be signed in to change notification settings - Fork 699
Allow both user-specific repo configs and repo configs managed by version control #6990
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
base: main
Are you sure you want to change the base?
Conversation
Please format the commits to adhere to our commit guidelines here: https://github.com/jj-vcs/jj/blob/main/docs/contributing.md#commit-guidelines and add a motivation to each commit. This is also missing tests and a changelog entry since the second commit even introduces a new command. |
I know, that's why it's a draft commit. Just want to make sure the concept is approved before I add finishing touches. |
e115b70
to
78f20ea
Compare
The idea sounds generally good to me. We might also want a similar mechanism for the zip file problem. Since the I have no idea about TUI. I personally would want to just see the diff and accept/reject. |
I'm not familiar with "the zip file problem". Could you link to the issue?
I'm not opposed to that. I chose this method because it was the same directory that the repo config was stored. I would request, however, that we submit this first and worry about that later, since this is explicitly not making the security any worse than it already is.
I do agree, as a user, that that's what I would want, but that's also relatively easy to achieve with the TUI. I think, however, that from a security perspective, a binary accept / reject choice is not great, because it might feel like you have to make a choice between new features and security. With a binary choice, if there's one particular line that you are concerned about and so you reject it, that means you have to reject every future change to the repo config. |
I don't think we have a link, but it's a familiar problem from other VCSs (familiar to VCS developers). The problem is what to do about repo-level configs in |
Makes sense. So I assume the solution would be to store it out of the repo, and require users to run |
I think Yuya's proposal was to record trusted config contents somewhere in I'm not sure if it's safe to trust configs at the key-value level or only at coarser granularity. Could there be some case where you say that you trust |
AFAICT, the attack surfaces are, in order of danger:
This is my analysis of the danger:
I think that it's possible to make one harmful thing and one alias to it, but I don't think it's possible to make two things that are independently safe but together harmful (it's technically possible with two arbitrary commands that execute files in the repo, but if they're doing that then they can already achieve this). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a bunch of actual review comments.
78f20ea
to
507083f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is probably OK. My worries are:
-
Is this too inflexible to be useful? For example, as the user jumps from commit to commit, the repo-managed config may change, and I don't see a way to decide automatically whether they want their config to change accordingly (even if we trusted the config; see my hash idea in the other comment for how we could).
-
How easy or hard will it be for the users to miss something important in the diff interface?
Figuring this out might require real-world testing. I'd probably merge some version of this, but disable it by default and call this feature "experimental" for quite a bit after. This is to give us time to polish it, but also to see whether it's worth the complexity/security tradeoff in practice.
Most of my other comments are various ideas about how to polish this further, which only make sense once we have a consensus that we're going forward with this (It's not clear to me how close we are at the moment).
My thoughts were, when designing this:
I think that if the user cares about security, it's pretty hard to miss. It is also relatively easy to just blindly approve, though.
I wouldn't be opposed to putting this behind a flag. Since this is inherently pre config-load, do you know if this would be able to be in our config schema, or would it have to be something like an environment variable flag? |
128b569
to
9359e03
Compare
I've added a config setting to toggle this feature, as requested by @ilyagr. Does anyone have opinions on what the config file should be? My candidates were:
I ended up settling on the last one for a few reasons:
That being said, I'd welcome other opinions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in general, my answer is:
There is a potential solution to this, but it's definitely not within the scope of the MVP. We can create a mapping from |
What if repo configs don't allow aliases? |
9359e03
to
b9e6224
Compare
That wouldn't really solve the problem. You could achieve the same just as easily with a malicious Also, I think that would somewhat defeat the point of the repo config. In chromium, for example:
While the former might be (somewhat) unique to chromium, I think that an alias So TLDR, I think they have too much value to disable. I think one approach that could be taken though is some stricter security measures. For example:
In general, sandboxing reads is a lot more painful, and I'm not sure it's a good idea, but sandboxing writes does sound like a very good idea. |
That feels like it's better as a follow-up PR, especially since I've disabled it with a feature flag by default. I think that the local directory is probably better in the long term, but in the short term I think there's nontrivial decisions that need to be made.
Sorry, my original PR renamed repo configs to user-repo configs, and called this "repo configs", but I didn't like that so I changed it. Updated the title to make it more clear.
Currently repo-managed configs are between the global user config and the repo's
This is the current behaviour, with the hope that in future versions we'll store a map from checked in config -> approved config instead of just remembering the most recently approved version.
As stated above, I think that for now we should store it in the
I think we would want to store:
I don't think we should worry about this use case. It's not frequent enough to be a concern.
Yeah, I was looking at this for chromium's fix tools. We have |
That's a very good point! I don't think we had considered that the config would contain repo-relative paths. I guess we'll have to think more about this. Sorry, that's all I have time to reply about right now. |
Just wanted to share some thoughts; I talked about some of this on the Discord before but wanted to get it posted here and expanded upon.
I agree that since I do also think that we should make
(The following treats configuration files in the working copy as monolithic things to accept or reject in their entirety, since I’m not sure the diff‐selecting interface makes sense if we move from just copying stuff into I agree that it makes sense to key trust on the repository, because configuration that you are okay with for one repository may not be okay for another. (For instance, perhaps the I am not sure to what extent it makes sense to include the other contents of the working copy in the threat model, however:
Therefore, I believe that our principle should be that changes to the working copy other than to the configuration file are out of scope for the threat model, and that users approving a configuration accept the risk of trusting the invoked tooling to handle it safely, or trusting arbitrary future states of the working copy itself if the approved configuration implicitly hands it privileges. (The latter does not necessarily make the feature useless, in the presence of a trusted remote enforcing ACLs or similar.)
FWIW, the direnv tool has been in the business of executing arbitrary code to set up development environments when you I think this is a broadly reasonable solution, especially if approvals for paths that no longer exist are automatically pruned. However, for Jujutsu, I wonder if we can’t do something that is both simpler and more effective, given our position as the VCS: why don’t we key approvals on, say, the hash of the That should close over the hashes of basically everything we could care about that contributes to the state of the configuration. We might want to throw in the workspace path too just in case you do something wonky with I think it’s best to err on the side of requiring re‐approval, because it’s only a mild annoyance unless you are cloning entirely new copies of a repository constantly, but being too lax is a CVE.
FWIW, my proposal for (We could also of course have a list of configuration options that are guaranteed to be safe to read from untrusted sources to reduce the prompting here, but it’s risky business if you haven’t architected your whole program for paranoia from the ground up; seemingly benign values can end up load‐bearing, especially in the presence of user configuration that looks at things like remotes.) |
Just an opinion: it's oh so much easier to avoid the risk when the tool never loads config from the repo it is managing. And that applies to all VCS, not just Edit: I forgot to mention, I was reading an article alleging the US 2024 election was manipulated, which tied back to a small approved change concerning the config file...that its hash was in the dynamic list instead of the static list to check for. This seemed related. |
IMO, the config of a VCS doesn't need to load config from the repo it's managing. However, by choosing to implement several features, I believe that I think that if a repo wants to tell a user how to format their code, that's fine. If a VCS wants to do formatting of code, that's also fine. But IMO you can't do both at the same time without allowing a repo to tell jj how to format their code. The same goes, in my opinion, for I strongly believe that adding this feature increases security, not decreases it. While you're right that this feature introduces potential security concerns, I think that by doing this you are ensuring that everyone does things in a relatively secure way. I think that if you do not add this feature, you will get things such as:
To use a metaphor, a door with a lock on it might not be perfectly secure, but if you don't make a door, people are gonna smash a hole through the wall, and that's definitely not secure. |
You didn't address what happens with multiple versions of the config file that get surfaced when you switch to that version, or when there are both a user and a repo config in the repo, or the CI hitting this approval thingy (command that isn't supposed to be interactive suddenly is). |
I've addressed these in earlier comments, but I'll reiterate:
When you switch to a version, you simply get a warning that you're using a different version of the config file. You can keep using your current version (as mentioned in previous commits, this isn't ideal, but is a good MVP, and I mentioned in an earlier comment a strategy we could use to improve on this by using hashes).
The order of application is (with the last overriding):
Nothing becomes interactive here. It simply outputs a warning that says "The config is out of date. We suggest updating the config by running
That's a fair opinion, and I think that if jj had chosen to go down that path, you'd probably be right that we don't need this, but I think that given the decisions that jj has made, this path is the right one. |
That's actually the opposite of what I thought, but I now see how what I said was ambiguous :) But as I think about it, I think only remembering "the most recently approved version" is probably a perfectly fine way to start. Repo-managed config shouldn't be changing often, so it isn't much of a problem in practice. (I previously had here a suggestion about using the diff editor to review config changes. Then I realized there was prior art for that: The implementation of the PR I'm commenting on. Whoops.) |
531cc29
to
7e83131
Compare
I was hoping we could get this reviewed and submitted soon. I think there are some open questions, but they're a non-issue for this particular PR IMO:
|
Has anyone looked up the discussions on other VCS using config from the repo it is managing, or is the only one? |
c881790
to
74f25a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Can we avoid the zip file problem
- It's definitely possible, but there's not a single solution. There's many different options we could take. I don't want to block this CL on a discussion on that, since this CL does not degrade security (it uses an insecure method, but it's the same method we already use for existing config files).
I prefer to address this security concern because repo-managed config is new feature, but I'm not strongly against adding it as the current form if people agree.
a423c36
to
786ac94
Compare
95d5c51
to
a4f5cb4
Compare
I agree with this, but it sounded like we couldn't come up with a solution that works for both cases because of the problem with approving a config that points a |
This can be used to add shared configuration across a repository. For example, all users should have the same `jj fix` within a given repository. This commit adds a new command, `jj config review-managed`, which is a mechanism to approve configuration checked in to the repo. See https://chromium-review.googlesource.com/c/chromium/src/+/6703030 for an example
a4f5cb4
to
85e8b5a
Compare
Fixes #3684
This adds the following workflow to jj to support repo-level workflows:
jj config update-repo
"jj config update-repo
adds a TUI requesting the user to approve the diffChecklist
If applicable:
CHANGELOG.md
README.md
,docs/
,demos/
)cli/src/config-schema.json
)