Skip to content
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

Implement secrets edit command #266

Closed
aryanjassal opened this issue Aug 26, 2024 · 13 comments
Closed

Implement secrets edit command #266

aryanjassal opened this issue Aug 26, 2024 · 13 comments
Assignees
Labels
development Standard development

Comments

@aryanjassal
Copy link
Contributor

aryanjassal commented Aug 26, 2024

Specification

If a secret doesn't exist when the edit command is invoked, then currently, the command just fails. Instead, the user needs to run polykey secrets create to copy a file from their file system and make that a secret, then they are able to use polykey secrets edit command. This is not great for UI/UX.

Moreover, each platform has their own preferences for file editor. As such, identify and launch the corresponding file editor to edit the secret. Windows would have notepad.exe, and MacOS and Linux editors would require to be inferred from environment. To ensure everything is working smoothly, integration tests need to be done on all the given platforms.

Generally speaking you rely on an environment variable: $VISUAL then if not set, rely on $EDITOR, and if not set, then you default onto something that would exist on most platforms.

https://unix.stackexchange.com/questions/4859/visual-vs-editor-what-s-the-difference

The "default" depends on some magic.

Here's our list depending on the OS.

  1. Linux - VISUAL, EDITOR, nano, ed - I wouldn't default to vi or vim because it's actually a more advanced editor.
  2. Windows - VISUAL, EDITOR, get the .txt file association first, then default to notepad.exe and wait for it to finish. Windows never had a default terminal text editor.
  3. MacOS - VISUAL, EDITOR, pico, nano

If the defaults cannot be found, you need to error out, indicating that no default editor could be found, and users can instead choose to set VISUAL, EDITOR or pass in the "editor" program with --ed or something.

Furthermore it is important that the temporary being created can only be edited by the same user as the user who ran polykey secrets edit, otherwise it can be intercepted. The file should have a limited umask like 700. Or equivalent for the Windows.

The behaviour of secrets edit command shouldn't be what is simplest. It should be what makes the most sense.

For example, instead of making a blank secrets file if it doesn't exist, ignore the part where the secret contents are fetched instead. Point the editor, say, vim to the temporary file, but don't make the file yet. If the editor exists without making the file, the action was cancelled. Do nothing. No need to make a file in the vault. If, on the other hand, a file which wasn't there before was created, then the user wants to make a new file with that contents. Then, make a new file with the contents that the user just entered. Otherwise, it should behave as it already has been.

The file should be in the temp directory under a random subdirectory. For example, a file I'm editing could look like /tmp/somedir-1234/file. The file name could be a constant, that doesn't matter. The directory it is under should be randomised. This appears to be the current default behaviour, so no changes are required for this.

Finally, consider concurrency. An agent can run multiple RPC commands concurrently. What happens when a file is edited at the same time another file is being edited? What if the same file is being edited in two separate agent commands? This would need to look into PCC and OCC for file locking. However, this has already been implemented in Polykey side, where it only allows a single operation to modify a file at a time.

The implementation should consider the changes to how the file creation is handled, and verify that the implemented behaviour for file randomisation and file locking is functional as intended.

Additional context

Tasks

  1. Create a new secret and edit it if a secret doesn't already exist.
  2. Rely on system editor to edit the secrets.
  3. Test for desired behaviour on all platforms.
@aryanjassal aryanjassal added the development Standard development label Aug 26, 2024
@aryanjassal aryanjassal self-assigned this Aug 26, 2024
Copy link

linear bot commented Aug 26, 2024

@MatrixAI MatrixAI deleted a comment Aug 26, 2024
@aryanjassal
Copy link
Contributor Author

I'm not sure how to handle checking if the file exists or not.

My first idea was to add a check to make an empty file if it doesn't already exist in all RPC handlers in Polykey, but that would break things and the behaviour would feel strange.

My second idea was to use the new ls command on Polykey CLI to see if the file exists, as on UNIX, if you ls a file, it would return only that file. However, simplicity and speed was prioritised, and this feature wasn't included in the current PR for the secrets ls command, so this can't be used either.

My third idea was to make an RPC handler on Polykey which checks if a file exists or not, but that seems like a lot of work for doing something seemingly simple.

All these ideas have their pros and cons, and I'm not sure which one to follow, or if I'm missing an easier solution.

@tegefaulkes
Copy link
Contributor

Part of the process is getting the file data to edit. You have two options here.

  1. Stat the file first. If the file doesn't exist then you'd get an ENOENT error and work from there.
  2. We should expand the file content serialiser to serialise errors it encounters when trying to open the file. This would just be the ENOENT error for the most part. Permission related errors would be possible but shouldn't happen for our usage since we don't use the file permissions in the vaults.

@aryanjassal
Copy link
Contributor Author

Stat the file first. If the file doesn't exist then you'd get an ENOENT error and work from there.

I thought error-driven workflow wasn't ideal as it takes a lot of resources to throw an error.

Perhaps alternatively, we can return something like null or undefined if the file doesn't exist at the time of vaultsSecretsGet? Or maybe extend its functionality to include a parameter which would create the file if it doesn't exist?

@tegefaulkes
Copy link
Contributor

Usually yeah, but for FS related stuff it's just how the API works. So in this case we just have to deal with it.

I know it's a contradiction of what I said earlier. But we can't really force our best practice on a library that's following an API pattern based on exit codes in a terminal.

@CMCDragonkai
Copy link
Member

You should copy over the editor detection and error if not found spec to the spec above, it's core to this issue, it shouldn't be just additional context.

Also some links for later cross platform testing:

Since they haven't been updated, it's likely the existing user accounts on those platforms is still the case. I have to update access for @brynblack.

How can we automate orchestration of the Mac and Windows machines? That's something to figure out later - new issue needed @brynblack. But for now, manual access for @brynblack acting as the Orchestrator is sufficient.

@CMCDragonkai
Copy link
Member

@brynblack I noticed that there's no mention of remmina for the 2 platforms. They are required for it.

@CMCDragonkai
Copy link
Member

@CMCDragonkai
Copy link
Member

Related cross platform testing for this: https://github.com/MatrixAI/Epsilon-Base/issues/3.

Copy link
Contributor Author

The behaviour of secrets edit command shouldn't be what is simplest. It should be what makes the most sense.

For example, instead of making a blank secrets file if it doesn't exist, ignore the part where the secret contents are fetched instead. Point the editor, say, vim to the temporary file, but don't make the file yet. If the editor exists without making the file, the action was cancelled. Do nothing. No need to make a file in the vault. If, on the other hand, a file which wasn't there before was created, then the user wants to make a new file with that contents. Then, make a new file with the contents that the user just entered. Otherwise, it should behave as it already has been.

The file should be in the temp directory under a random subdirectory. For example, a file I'm editing could look like /tmp/somedir-1234/file. The file name could be a constant, that doesn't matter. The directory it is under should be randomised. This appears to be the current default behaviour, so no changes are required for this.

Finally, consider concurrency. An agent can run multiple RPC commands concurrently. What happens when a file is edited at the same time another file is being edited? What if the same file is being edited in two separate agent commands? This would need to look into PCC and OCC for file locking. However, this has already been implemented in Polykey side, where it only allows a single operation to modify a file at a time.

Implement the changes to how the file creation is handled, and verify that the implemented behaviour for file randomisation and file locking works.

@CMCDragonkai
Copy link
Member

The behaviour of secrets edit command shouldn't be what is simplest. It should be what makes the most sense.

For example, instead of making a blank secrets file if it doesn't exist, ignore the part where the secret contents are fetched instead. Point the editor, say, vim to the temporary file, but don't make the file yet. If the editor exists without making the file, the action was cancelled. Do nothing. No need to make a file in the vault. If, on the other hand, a file which wasn't there before was created, then the user wants to make a new file with that contents. Then, make a new file with the contents that the user just entered. Otherwise, it should behave as it already has been.

The file should be in the temp directory under a random subdirectory. For example, a file I'm editing could look like /tmp/somedir-1234/file. The file name could be a constant, that doesn't matter. The directory it is under should be randomised. This appears to be the current default behaviour, so no changes are required for this.

Finally, consider concurrency. An agent can run multiple RPC commands concurrently. What happens when a file is edited at the same time another file is being edited? What if the same file is being edited in two separate agent commands? This would need to look into PCC and OCC for file locking. However, this has already been implemented in Polykey side, where it only allows a single operation to modify a file at a time.

Implement the changes to how the file creation is handled, and verify that the implemented behaviour for file randomisation and file locking works.

That should be part of the spec.

Copy link
Contributor Author

aryanjassal commented Sep 10, 2024

I have implemented the creation of a file if it doesn't already exist in the vault. The remaining tasks for this issue will be tracked in #277 (ENG-405).

@CMCDragonkai
Copy link
Member

You should copy over the editor detection and error if not found spec to the spec above, it's core to this issue, it shouldn't be just additional context.

Also some links for later cross platform testing:

Since they haven't been updated, it's likely the existing user accounts on those platforms is still the case. I have to update access for @brynblack.

How can we automate orchestration of the Mac and Windows machines? That's something to figure out later - new issue needed @brynblack. But for now, manual access for @brynblack acting as the Orchestrator is sufficient.

Has the cross platform testing been done?

PROBABLY not! Because you need access to the mac and windows machines, and I haven't delegated due to lack of store-and-forward convenience. That's for manual sanity checks.

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

No branches or pull requests

3 participants