ironcorelabs / ironhide Goto Github PK
View Code? Open in Web Editor NEWTool to easily encrypt and decrypt files to users and groups. Similar to GPG, but usable at scale.
License: GNU Affero General Public License v3.0
Tool to easily encrypt and decrypt files to users and groups. Similar to GPG, but usable at scale.
License: GNU Affero General Public License v3.0
❯ ironhide device:list
(node:13556) TypeError Plugin: @ironcorelabs/ironhide: Cannot read property 'dim' of undefined
module: @oclif/[email protected]
task: runHook command_not_found
plugin: @ironcorelabs/ironhide
root: /Users/ernie/.nvm/versions/node/v12.16.2/lib/node_modules/@ironcorelabs/ironhide
See more details with DEBUG=*
› Error: command device:list not found
If I run ironhide file decrypt a/file.iron
, it writes the output to file
. To maintain compatibility with previous ironhide, it should write output to a/file
.
This is an epic tracking all the package managers we'd like to release to and support.
Use Case: you are generating keys to put on a machine where you can't log in and run a web browser to do the auth0 flow. Instead, run ironhide
on a machine where you do have a browser, and might already have keys generated, but run a genkeys
command that causes IronHide to ignore the existing keys, generate a new set of keys, and just print the JSON to stdout. You can cut and paste it, redirect to a file, or pipe into an SSH that cats the input into a file on the remote machine.
It's likely that when we pump the ironhide
that this action uses by a major version we'll bump the action itself by a major version. We should update v2
/main
to be installing ironhide@^0.8.x
instead of the always latest that it's getting now (which may cause breakage if the required node version goes up in latest
).
Create an action to release to homebrew
to support Mac users. They have a guide on how to do this. They apparently don't like package producers to be the ones maintaining the formulae, so we may need to initially release in a tap
instead.
Add install instructions to the README.md as well.
We currently have a limit within IronHide to restrict users from only performing operations on at most 75 files at a time (encrypt/decrypt/grant/revoke/info). This limit is fairly arbitrary but was meant to prevent thrashing the server and potentially getting the user into a Cloudflare rate limiting state. A better solution would be to batch up these requests and perform then in 10-file batches at a time before processing the next batch.
When using ironhide, I'd like it to be very clear when operations fail. Since file operations support partial failure, we currently just log the failures and process the successes and move on. In the case where all operations have failed, I think it would be better to return an error code so it's clear that it was a total failure.
This could be done by changing util::act_on_all_files
to return a Result<(), String>
and returning Err
when there are no successes.
File decryption output is not visible when using ironhide in GitHub Actions. We use this function for our output (or println_paint
):
pub fn print_paint(paint: yansi::Paint<String>) {
// only print to stdout if we're not being piped somewhere
if atty::is(atty::Stream::Stdout) {
print!("{}", paint);
}
}
I assume the condition is failing in this environment, in which case we print out nothing.
The atty
also seems abandoned.
Produce man pages and useful completions for ironhide users.
We can generate shell completions using clap
as part of our build process. See ripgrep
for examples of including completions in the build artifacts.
We can also generate man pages for the tool in a similar way.
The tool builds fine on MacOS, so installations using homebrew
or otherwise building from source will work fine. Someone downloading pre-built binaries off Github Releases though won't be able to run the tool unless they bypass security rules.
We can sign and notarize our pre-built x86_64 and arm64 binaries to make them securely runnable on MacOS.
If a .iron file decrypt is attempted and the decrypt fails for some reason (other than that the output file exists), the output file is created and is left empty.
Clean up code safety, handle errors more intelligently. Right now everything is either manually printed where it happens or bubbles up to a Box<dyn Error>
which isn't very useful. At least use something like anyhow
to let us capture stringy errors wherever they happen and bubble them up to sane places to handle them in a combined way.
If a user has access to a file that is encrypted to a group that they are not a part of via
ironhide file:info file.iron
Then they get an error that says:
Error: Cannot read property 'groupName' of undefined
This is because we had previously assumed that the user is always in the groups that comes back in the document visibility list. This changed at some point in the past so now it also returns the IDs of the groups that the user is not a member/admin of.
Best idea to fix this is to just omit the groups in the table that the user is not part of.
Currently keyring support works if all the things it needs are present, and if it doesn't work it silently fails. Either way right now keys are still written to disk as a backup. Improve the keyring support so it's more robust. Alter the login/creation flows so that if the keyring is present and working we don't write anything but login
to .iron
.
Create an action to release to the Ubuntu package repository. They have a guide on how to do this. If other debian distros could easily be supported by the same action, make tickets for them as well.
Add install instructions to the README.md as well.
This currently affects our build systems in Travis that use ironhide for build secrets.
The high level summary seems to be that node-pre-gyp
broke because node-tar
broke because of an issue with minipass
. Versions aren't pinned on the way down, so a random release of minipass broke things all the way up.
mapbox/node-pre-gyp#477
isaacs/node-tar#232
isaacs/minipass#9
According to lovell/sharp#1882 (comment) pinning minipass to v2.7.0 in this project would resolve.
When we do a user:lookup
and we display the users public key as base64 x/y, most people don't know what that means. We should either combine that to just display a single Base64 string, or just nuke it entirely and display a checkmark that denotes that the user has a public key.
It's not obvious what the fromUser
and fromGroup
text that we display in this column means. We should clean up that text and map it to something that's more clear.
When we log long words to stdout or stderr they can end up getting wrapped at non-ideal locations in the middle of words. This is a bigger issue for when we log text in the login process which dumps out quite a bit of text.
The oclif/help-plugin
uses the wrap-ansi
plugin along with the following code to wrap at the window width
function termwidth(stream: any): number {
if (!stream.isTTY) {
return 80;
}
const width = stream.getWindowSize()[0];
if (width < 1) {
return 80;
}
if (width < 40) {
return 40;
}
return width;
}
const columns: number | null = parseInt(process.env.COLUMNS!, 10) || (global as any).columns;
console.log(columns || termwidth(process.stdout));
console.log(columns || termwidth(process.stderr));
If a user performs a user:lookup
command and the user doesn't exist, we should provide a simple way for them to "invite" the user. This might be as simple as just dumping out a mailto: link in the console.
Use https://docs.rs/clap_complete/latest/clap_complete/generator/fn.generate_to.html to generate completions as part of our build (and distribute in the release) for popular shells.
Display results in table when displaying a list of groups or documents. Also display during group name resolution display.
When I run ironhide file:info {some_file}
, I get output like this:
┌──────────────────────────┬───────────────────────────┬───────────────────────────────────────────┬───────────┬───────────┐
│ File │ Users with access │ Groups with access │ Created │ Updated │
├──────────────────────────┼───────────────────────────┼───────────────────────────────────────────┼───────────┼───────────┤
│ {some_file} │ [email protected] │ ICL-IT (48dc3c20d11bfd9f408c204e24a248f9) │ 12/6/2018 │ 12/6/2018 │
└──────────────────────────┴───────────────────────────┴───────────────────────────────────────────┴───────────┴───────────┘
It's not easy for a script to parse output like this. It would be nice to have an option to produce machine readable output, possibly:
Create an action to release to nix
/nixos
. They have a guide on how to do this.
Add install instructions to the README.md as well.
On encrypt, if I specify a filename for output, it works as expected, but the screen message uses the assumed filename instead of the specified one, which is incorrect:
% ironhide file:encrypt -d plaintext.txt -o ciphertext.iron
Encrypted file successfully written to plaintext.txt.iron.
% ls plain*
zsh: no matches found: plain*
% ls cipher*
ciphertext.iron
% ironhide file:decrypt -d ciphertext.iron -o plaintext.txt
File successfully decrypted and written to ciphertext.
% ls cipher*
zsh: no matches found: cipher*
% ls plain*
plaintext.txt
Executing ironhide file decrypt --help
indicates
USAGE:
ironhide file decrypt [OPTIONS] <FILES>...
However, a command like ironhide file decrypt -o test-file file.iron
generates the error
error: The following required arguments were not provided:
<FILES>...
USAGE:
ironhide file decrypt --out <OUT>... <FILES>...
Putting a .iron
file name before the --out
does allow the file to be decrypted.
Update the command line parser so it will accept the -o
option before the file list.
NOTE: the -k <keyfile
option does work before or after the list of files.
So people depending on the flake directly don't have failures.
tw user:changePassword
No arguments or flags, displays a series of prompts asking the user for their current password, new one, and confirm. Should also display text telling the user that any existing devices would continue to work.
oflif
has documentation on how to do unit testing of a CLI tool. We should look into adding them.
Upgrade library to add windows support, expose method to let users change their escrow password
Is that IronCore service an open source project? Ironhide seems to rely much on that IronCore service.
I told ironhide to decrypt 3 files, one of which didn't exist. (I left off the .iron
extension.) It decrypted the other 2, and then it exited successfully.
$ ironhide file:decrypt .env.iron assertionKey.json IronCore_Dev_1-f46ac7bde6af.json
Provided path '/home/travis/build/IronCoreLabs/cmk-config-broker/assertionKey.json' doesn't exist or is not readable.
Provided path '/home/travis/build/IronCoreLabs/cmk-config-broker/IronCore_Dev_1-f46ac7bde6af.json' doesn't exist or is not readable.
1 file(s) successfully decrypted.
2 file(s) failed to be decrypted.
If an operation fails, the program should exit with a nonzero status.
Release to crates.io so cargo install ironhide
works. Update the README with install instructions.
% ironhide group info ICL-all
thread 'main' panicked at 'Must be run on a system that has an OS time library.: IndeterminateOffset', /Users/bob/.cargo/registry/src/github.com-1ecc6299db9ec823/ironhide-1.0.0/src/util.rs:168:39
Other commands like file info and user lookup work as expected.
Create an action to release to the Arch package repository. There is a guide on the wiki, as well as other ones not specific to Rust with more detail. We may need to release to the AUR initially. Optionally we could support a -bin
package that just downloads from the github releases instead of building from source.
Add install instructions to the README.md as well.
I would like the permissions of the files in ~/.iron
to be more restrictive, so that other users on a shared system would have a harder time seeing my device keys.
I am on Linux, and I think good permissions would be 600
. I'm not sure how that would work in Windows, if you are supporting that.
Maybe everything in .iron could always be created with these restricted permissions? The most important one to me is .iron/keys
.
Use our in-house arm64 runner to support MacOS arm64 CI and pre-built binaries.
Create an action to release to chocolatey to support Windows users. There is a guide created by them.
Add install instructions to the README.md as well.
repro:
ironhide login
Error message is Provided passphrase was invalid. Please try again.
We should make it clear that times printed to the console are printed in the users TZ, and it'll help clarify when we're displaying the DST timezone of the current timezone (vs the actual current TZ). This goes a bit of the way towards #82
Create a test suite that replicates the one we've lost.
We could accomplish this with secrets containing keys generated for a test user that would allow for full functionality of a user to test inputs and outputs against the IronCore service. This would probably the most useful set of tests as far as confirming end user functionality, but they'd be integration tests.
Another option would be to do what the original tests did and mock responses from the IronCore service, unit testing that expected commands function, send calls to the expected REST endpoints, and display the expected results given the canned responses. This may be harder given current Rust tooling.
https://bitheap.org/cram/
https://github.com/assert-rs/trycmd
https://crates.io/crates/snapbox
https://crates.io/crates/assert_cmd
https://crates.io/crates/assert_fs
E.g.
let created_dt = device.created().to_offset(util::local_offset());
does not look correct to me. I only gave it a cursory glace, though. If the user's time zone changed since the device was created, e.g. because the clocks clocks were change, or the user traveled into another time zone, the information will be bogus.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.