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

Sign EIFs separately #652

Merged
merged 2 commits into from
Jan 29, 2025
Merged

Sign EIFs separately #652

merged 2 commits into from
Jan 29, 2025

Conversation

atanzu
Copy link
Contributor

@atanzu atanzu commented Jan 23, 2025

Issue #, if available:
#204

Description of changes:

This PR allows to sign pre-built EIFs using the new sign-eif command. Users can use either a local private key, or a KMS key.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@atanzu atanzu force-pushed the feature/sign-eifs-separately branch from 79f9243 to eff4299 Compare January 24, 2025 07:19
@atanzu atanzu marked this pull request as ready for review January 24, 2025 07:53
@@ -195,6 +195,12 @@ fi
%{ne_include_dir}/*

%changelog
* Thu Jan 23 2025 Mark Kirichenko <[email protected]> - 1.4.0-0
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this change and the version bump in Cargo.toml should be published as a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack, removed this commit from the PR branch

sources Outdated
@@ -1 +1 @@
23d02e54e9571764baa45425e1a873936e6ad338 nitro-cli-dependencies.tar.gz
4b6d694643b6c4723658d5a7b2797103875c269a nitro-cli-dependencies.tar.gz
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

.help("Local path to developer's X509 signing certificate."),
)
.arg(
Arg::new("private-key")
Copy link
Contributor

Choose a reason for hiding this comment

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

I have concerns about including this feature in the new command. This approach to handling private keys doesn't follow security best practices. While I understand the desire to maintain consistency with the build-eif command, I recommend removing this feature from the sign-eif command entirely.

If there are compelling reasons to keep it, we should:

  • Add detailed explanation in the help text explaining the security implications
  • Implement warning messages to alert users that this is not the recommended approach for private key handling

CC: @eugkoira

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My vision is, we might have customers who build EIFs in one (insecure) environment, and then sign those EIFs separately in a secure environment with a local private key, similar to #639.

Copy link
Contributor

@eugkoira eugkoira Jan 24, 2025

Choose a reason for hiding this comment

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

I don't get it, is the proposal to not have the private-key signing at all?
Why is it a bad practice?

Copy link
Contributor

Choose a reason for hiding this comment

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

We all know what could happen if a private key is leaked. :) Given the security risks associated with private key exposure, the users should be encouraged to use KMS as the recommended best practice. (Or using PKCS#11 in the future. This was also mentioned by @dwmw2 here.)

I believe there are two options:

  • Omit local private-key signing for sign-eif command and mark the argument in build-eif as deprecated
  • Keep private-key as an option for sign-eif but add warnings about security implications.

Copy link
Contributor

Choose a reason for hiding this comment

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

Customers can still have a secure isolated environment for signing with a private key like in #639. Why should we restrict their possibilities?

We can specify in our documentation the recommended way but I don't understand the urge to remove it completely.

Copy link

Choose a reason for hiding this comment

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

Customers can literally use Nitro Enclaves to receive the signing key from KMS and pass it as parameter here, right? I don't believe the tool should per se assume an insecure environment. To clarify environmental requirements and establish best practices is the task of our documentation.

Copy link

@dwmw2 dwmw2 Jan 24, 2025

Choose a reason for hiding this comment

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

Signing requires a private key. That's kind of fundamental. The question is where that private key is found.

The real problem here seems to be that we have two completely separate command line arguments to provide the private key. There's the --private-key argument, which makes sense. A user will reasonably expect to be able to pass that a filename, an RFC7512 PKCS#11 URI, and maybe other kinds of things like a TPM URI referencing keys in non-volatile storage (although that's kind of dead now, and mostly a user would expect to provide a PEM file with a TPM-wrapped key and have that Just Work too).

And then we have the --kms-key-id argument. Which probably should have just accepted an ARN for a KMS key, e.g. --private-key arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321, from the start? If we're talking about cleaning up the user interface, I'd much prefer us to deprecate --kms-key-id and use only --private-key to tell the tooling which private key to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that having a single parameter which dispatches internally basing on the provided value is the best option in terms of UX, and good thing that --kms-key-id has only been introduced to mainline, there is no actual release which fixed that in stone.

Copy link

Choose a reason for hiding this comment

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

good thing that --kms-key-id has only been introduced to mainline, there is no actual release which fixed that in stone.

Excellent. So let's fix that to use --private-key arn:aws:kms:… before ever releasing it.

.help("Path pointing to a prebuilt Eif image")
)
.arg(
Arg::new("signing-certificate")
Copy link
Contributor

Choose a reason for hiding this comment

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

If we decide to retain the local signing option, this should be --signing-certificate-path for clarity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How I see it, the parameter names shall be the same as the ones used when signing an image during build. Updating syntax for build-enclave is a breaking change unless we keep both the old parameter name and the new one, plus add a deprecation warning.

Copy link
Contributor

Choose a reason for hiding this comment

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

I vote for consistency with what we already have

Copy link
Contributor

Choose a reason for hiding this comment

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

we keep both the old parameter name and the new one, plus add a deprecation warning

Yes, this is what I meant. To clarify, --signing-certificate or --private-key should remain in place until the next major release of nitro-cli.

)
.arg(
Arg::new("private-key")
.long("private-key")
Copy link
Contributor

Choose a reason for hiding this comment

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

If we decide to retain the local signing option, this should be --private-key-path for clarity.

Copy link
Contributor

Choose a reason for hiding this comment

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

it will be inconsistent with build-eif experience and can bring more confusion then benefits

let kms_key_id = parse_kms_key_id(args);
let kms_key_region = parse_kms_key_region(args);

validate_signing_credentials(&signing_certificate, &private_key, &kms_key_id)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

a bit weird that kms_key_region is not validated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is OK to have it empty, AWS client will try to get the region from env or uses the default one.

Copy link
Contributor

Choose a reason for hiding this comment

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

no, I mean potentially we could have region and private key at the same time

Copy link

Choose a reason for hiding this comment

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

Which is why you could just pass the ARN of the KMS key in as the --private-key argument... :)

eugkoira
eugkoira previously approved these changes Jan 24, 2025
src/lib.rs Outdated
Arg::new("kms-key-region")
.long("kms-key-region")
.help("Specify region in which the KMS key resides")
.requires("kms-key-id")
Copy link
Contributor

Choose a reason for hiding this comment

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

also testing those rules same as for build-eif would be beneficial

This commit allows to add or update signature of already existing EIFs.

Signed-off-by: Mark Kirichenko <[email protected]>
This commit adds tests cases to validate the signing functionality.

Signed-off-by: Mark Kirichenko <[email protected]>
@atanzu atanzu merged commit a79f794 into main Jan 29, 2025
14 checks passed
@atanzu atanzu deleted the feature/sign-eifs-separately branch January 29, 2025 15:37
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.

5 participants