Skip to content

Autoenv rewrite, security and scripting#2083

Merged
sophiajt merged 176 commits intonushell:masterfrom
samhedin:direnv-rewrite
Jul 5, 2020
Merged

Autoenv rewrite, security and scripting#2083
sophiajt merged 176 commits intonushell:masterfrom
samhedin:direnv-rewrite

Conversation

@samhedin
Copy link
Copy Markdown
Contributor

@samhedin samhedin commented Jun 30, 2020

Autoenv

You no longer have to restart nushell after using autoenv trust. On startup, nushell reads nu-env.toml and stores the trusted files and their hashes. It uses the sha2 crate to allow for predictable hash values, since DefaultHasher can change between versions. This was by request, and if it would be better to avoid adding the dependency, it is simple to revert back to DefaultHasher.

Autoenv trust/untrust

You mark a .nu-env file as trusted or untrusted by running autoenv trust or autoenv untrust in the directory it is in, or by giving the commands the dir path.
If you enter a directory with a .nu-env file which was either not trusted on startup, or has a different hash than it had on startup, nu-env.toml is read again and the .nu-env hash is checked against it.
You still need to restart after using autoenv untrust, as I could not come up with a good way to reload this. Just re-reading nu-env.toml all the time would work, but it also feels wrong to read a file all the time like that.

Scripting

In addition to env, each .nu-env file may now contain the lines entryscripts, exitscripts and the section scriptvars.
The keys in scriptvars must point to a valid command which resolves to a value. After that, the key and value are tracked and removed by nushell like regular environment variables listed under env.
Commands in entryscripts and exitscripts are run when you enter and after you exit a directory. Nushell takes no responsibility for these and does not even show their output. Note that exitscripts are not run inside the directory they are declared in.
[edit: new toml format]

[env]
k = "v"

[scriptvars]
myscript = "echo 'myval'"

[scripts]
entryscripts = ["touch hello.txt"]
exitscripts = ["touch bye.txt"]

All comments appreciated! Please do test it if you can.

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 2, 2020

Alright! Another commit, another try. The format has now changed. The script section and its keys (entryscripts and exitscripts) are optional.

[env]
k = "v"

[scriptvars]
myscript = "echo 'myval'"

[scripts]
entryscripts = ["touch hello.txt"]
exitscripts = ["touch bye.txt"]

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 2, 2020

Question: Should autoenv give an error message if any section is missing (i.e env, scriptvars, scripts) or just be quiet and happy about it?

@rrichardson
Copy link
Copy Markdown
Contributor

@samhedin - I'd say it should be quiet and only work with what it is given.

@sophiajt
Copy link
Copy Markdown
Contributor

sophiajt commented Jul 2, 2020

@samhedin - gave it a go. If I do:

> autoenv trust .

I'm able to trust the current .nu-env, and it looks like it works great without a restart.

I ran into an issue if I try to untrust in the same session:

> autoenv untrust .

If I cd into and out of the directory, I still see environment variables come and go as if the file was trusted, even though it should now be untrusted.

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 2, 2020

As I said in the original post, I didn't want to hot-reload after autoenv untrust since this would require re-reading from nu-env.toml every time you enter a command. I was afraid of how this would impact people who are running scripts inside nushell.

But things changed - now there are checks to make sure autoenv is only run once per directory change, so maybe it is fine to do IO each time. Have a look at the latest commit, changes from trust and untrust should be applied after changing dir, hopefully without slowing any scripts down!

@sophiajt
Copy link
Copy Markdown
Contributor

sophiajt commented Jul 3, 2020

@samhedin Cool, will keep an eye open for performance issues.

I was just trying the same test again, and getting the same result.

If you're in a trusted directory, and you untrust it, do you still see the same environment variables?

Feels like we're close.

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 3, 2020

Did it work out alright? Untrusting a directory will not immediately unset the variables - you need to leave the directory as usual. Untrust only prevents any new variables and scripts from running. Is this alright behavior?

@rrichardson
Copy link
Copy Markdown
Contributor

I think the behavior of Direnv is that it actively strips any env vars that it controls when you "un-allow" a .envrc (directory)
That is the behavior I would have expected, but we should decide if that's actually the behavior we want.

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 3, 2020

Huh, interesting. I would have expected the current behavior to be the norm. I don't believe that this would be a trivial change, but if it's requested I will of course give it a proper go.

@sophiajt
Copy link
Copy Markdown
Contributor

sophiajt commented Jul 3, 2020

@samhedin - I think it's worth giving it a try, and seeing if it's doable.

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 4, 2020

If you run autoenv untrust in a directory, do you think that it should
a) remove all vars set by the directory and run its exitscripts
b) remove all vars set by the directory and not run its exitscripts

@thegedge
Copy link
Copy Markdown
Contributor

thegedge commented Jul 4, 2020

I'd lean towards (b). I know that could leave things in a weird state, but I think when we trust a directory, we trust it to run the scripts. When we untrust, we take back that trust and probably shouldn't run the scripts. I'd start there, at least.

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 4, 2020

I agree. I want to add that for a while I didn't even consider adding autoenv untrust. How common will it be to untrust a file you trusted previously? Not very common, I expect, since any changes would invalidate it anyway, and if you don't want it you could just delete the file itself.
Anyway, it's all ready to be tried out!

One issue remains: Vars set by ~/.nu-env are persistent across sessions(!!).

[edit]
Or they're not persistent? I am so confused it is actually insane. Are there env var caches? Vars I set long ago in the home folder stick around even if I remove them from ~/.nu-env, but new ones work as expected.

@sophiajt
Copy link
Copy Markdown
Contributor

sophiajt commented Jul 4, 2020

@samhedin - is it possible that it's going up into a parent directory and finding something?

@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 4, 2020

This was my initial thought too, but nope. I can't reproduce the behavior anymore though...

@sophiajt
Copy link
Copy Markdown
Contributor

sophiajt commented Jul 5, 2020

Did some testing with the trust/untrust, scriptvars, and scripts. Things look good enough we should land this so we can use it and continue improving it based on how it feels in practice.

Thanks again for putting all this together!

@samhedin - I did notice that the paths in my nu-env.toml weren't canonical at one point but then couldn't reproduce it. Maybe you fixed something along the way?

@sophiajt sophiajt merged commit ee18f16 into nushell:master Jul 5, 2020
@samhedin
Copy link
Copy Markdown
Contributor Author

samhedin commented Jul 5, 2020

Did some testing with the trust/untrust, scriptvars, and scripts. Things look good enough we should land this so we can use it and continue improving it based on how it feels in practice.

Super exciting! I am ready for a stream of bug reports.

@samhedin - I did notice that the paths in my nu-env.toml weren't canonical at one point but then couldn't reproduce it. Maybe you fixed something along the way?

Yes! At some point I started using std::fs::canonicalize instead of... whatever I was using before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants