Skip to content

Add configurable verification policies + access to system sequoia config - #91

Open
dralley wants to merge 3 commits into
wiktor-k:mainfrom
dralley:main
Open

dralley wants to merge 3 commits into
wiktor-k:mainfrom
dralley:main

Conversation

@dralley

@dralley dralley commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator

Expose StandardPolicy for verification and decryption, including scoped hash security overrides for legacy SHA-1 compatibility. Document the policy API and cover SHA-1 policy behavior.

Assisted-By: Codex 5.6 Terra

@dralley
dralley force-pushed the main branch 2 times, most recently from 5965064 to 82949bb Compare October 1, 2026 22:36
@dralley dralley changed the title Add configurable verification policies Add configurable verification policies + access to system sequoia config Oct 2, 2026
@dralley
dralley marked this pull request as ready for review October 2, 2026 02:29
@dralley
dralley requested a review from wiktor-k October 2, 2026 02:29
Comment thread README.md Outdated
### Using a system policy configuration

To explicitly use a Sequoia policy managed by the operating system, load and
pass it to the operation. This does not happen automatically.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Alternatively it could try to look up the system config, and maybe fall back to the default if not found. That would be a bit more similar to what openssl does.

As an architectural decision I figured this made the most sense though.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

FWIW I like the current one since it's explicit with no magic involved. 👍

@dralley

dralley commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator Author

@wiktor-k Would it also make sense to expose the hash algorithm option when signing? It would at least help with testing this

@dralley

dralley commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator Author

I added the aforementioned hash algorithm option.

@wiktor-k Do you think you will have time to review this week?

@wiktor-k

wiktor-k commented Oct 6, 2026

Copy link
Copy Markdown
Owner

@wiktor-k Do you think you will have time to review this week?

I might. In general I like the idea (as baking in StandardPolicy everywhere was kind of an ugly workaround) but I see some potential for improvement. Sadly there's much professional work on my side (including weekends) and I don't want to rush API changes.

Thanks for your patience! 🙏

@tstringer-optaxe

Copy link
Copy Markdown

It would be great to be able to configure these for verifying older signatures.

@wiktor-k wiktor-k left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Looks mostly fine. A bit of naming consistency and I guess we can ship this.

Would you be so kind and provide a rationale for what do you need these for (mostly for my curiosity)?

Comment thread NEXT.md Outdated

New:
- Add configurable cryptographic policies, including system Sequoia policy profiles and legacy SHA-1 signature verification.
- Allow selecting the hash algorithm when signing data or files.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

What's the actual use case for selecting hash algorithm for signing? 🤔

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't have a really solid use case for it beyond testing the policy, at least we don't particularly have a use case for it, but OTOH it's still sequoia_openpgp exposed functionality.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

FWIW I can drop the commit if you prefer, it's not considered necessary

Comment thread python/pysequoia/__init__.pyi Outdated
"""

def decrypt(bytes: bytes, decryptor: PyDecryptor |None = None, store: Any |None = None, passwords: Sequence[str] = ...) -> Decrypted:
def decrypt(bytes: bytes, decryptor: PyDecryptor |None = None, store: Any |None = None, passwords: Sequence[str] = ..., policy: StandardPolicy |None = None) -> Decrypted:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I'm not happy with all these functions taking StandardPolicy. In Sequoia StandardPolicy implements the Policy trait and all functions take that trait thus avoiding concrete implementations in the public API.

If we need structs for pyo3 then I guess we could rename StandardPolicy to just Policy and have constructors (say Policy.standard()) which return a policy prefilled with the defaults of standard policy.

Wdyt?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed, that sounds fine

Comment thread README.md Outdated
### Using a system policy configuration

To explicitly use a Sequoia policy managed by the operating system, load and
pass it to the operation. This does not happen automatically.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

FWIW I like the current one since it's explicit with no magic involved. 👍

@dralley

dralley commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Would you be so kind and provide a rationale for what do you need these for (mostly for my curiosity)?

Because they started rolling out the newer version of our software w/ pysequoia to an internal service, and quickly discovered that there were still a number of in-use keys still using sha1 in binding signatures - the signatures therefore were being rejected during validation.

(they will be rotated but it'll take some time)

@wiktor-k

wiktor-k commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Because they started rolling out the newer version of our software w/ pysequoia to an internal service, and quickly discovered that there were still a number of in-use keys still using sha1 in binding signatures - the signatures therefore were being rejected during validation.

(they will be rotated but it'll take some time)

Understood. Thanks for the rationale!

For that though the policy from system and configurable policies are not really necessary? (I'm trying to cut the amount of code to bare minimum since more code == more bugs and more maintenance burden). Unless there's additional compliance issue with pysequoia on redhat here? (Sorry for prodding so much 😅 )

@dralley

dralley commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator Author

Let me know if I should just drop the hashalgorithm commit, and then I can squash/update the other 3.

For that though the policy from system and configurable policies are not really necessary?

Well I think the alternative is to override the policy in code and universally accept SHA1, which I don't think we want to do. I'm not even sure it's something all internal users would want much less external ones.

We could make that configurable in a Pulp setting instead, but it feels wrong and might need to be redone later if there was some other knob that needs to be tweaked.

Pulp is repository management software w/ both hosted services and on-prem users (both product and direct users of the upstream open source code), lots of those on-prem users are the type that have the desire or legal requirement to lock things down to various government security standards. So from that standpoint respecting system-configured policy seems like the correct approach. That's how other applications using something like openssl would get locked down, so it keeps things consistent.

Unless there's additional compliance issue with pysequoia on redhat here?

I mostly just don't want to make assumptions about what should and shouldn't be permitted, different users would want/need different things. But making sure it's possible to enable compliance with various current and future standards is part of the motivation, yeah.

@dralley

dralley commented Oct 13, 2026

Copy link
Copy Markdown
Collaborator Author

@wiktor-k Does that make sense?

@wiktor-k

Copy link
Copy Markdown
Owner

@wiktor-k Does that make sense?

Yeah it does. I just got stuck thinking about the interaction of system policies and packaging of pysequoia.

So, I've noticed that packaged pysequoia already configures openssl backend instead of rust: https://src.fedoraproject.org/rpms/python-pysequoia/blob/rawhide/f/python-pysequoia.spec#_57 and I was wondering whether we would rather want a compile-time toggle that'd enable and force system policy always on redhat systems. Does it make sense to use a different policy on a redhat system where the administrator disabled some algos?

Additional question (maybe @michaelkuhn can help here?) - if redhat systems already use openssl backend would it imply that the system policy is already being enforced on the openssl level?

Sorry that I'm not being easy on this one @dralley... I just want to avoid pulling more sequoia deps if this can be avoided... if not then this PR looks good already 👍

@dralley

dralley commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator Author

No worries, I understand. There is already a workaround in place so it's not so time sensitive as to cause a rush

Re: openssl config, I believe there is a distinction made between SHA-1 as part of an OpenPGP binding signature vs. a SHA-1 data signature, and I don't think openssl-level configuration would be able to make that distinction. It's just providing the basic crypto primitives. So the sequoia config still provides some value that can't be replicated by just tweaking openssl.

For PyPI builds, none of this is really relevant, since I don't think they could use OpenSSL any time soon given pypi/manylinux builds include their own copy of OpenSSL which is too old to enable PQC. The Rust backend is the only real option there and even if they could use OpenSSL, I don't think that the vendored OpenSSL actually respects the system configuration without manual intervention (I think you can set some environment variables or something, but I'm sure that also comes with caveats on config compatibility between the system and vendored version).

As far as the feature flag goes, that's more a question for @michaelkuhn. I can also ask a coworker who deals with packaging more than I do.

@wiktor-k

Copy link
Copy Markdown
Owner

Re: openssl config, I believe there is a distinction made between SHA-1 as part of an OpenPGP binding signature vs. a SHA-1 data signature, and I don't think openssl-level configuration would be able to make that distinction. It's just providing the basic crypto primitives. So the sequoia config still provides some value that can't be replicated by just tweaking openssl.

Good point.

For PyPI builds, none of this is really relevant, since I don't think they could use OpenSSL any time soon given pypi/manylinux builds include their own copy of OpenSSL which is too old to enable PQC. The Rust backend is the only real option there and even if they could use OpenSSL, I don't think that the vendored OpenSSL actually respects the system configuration without manual intervention (I think you can set some environment variables or something, but I'm sure that also comes with caveats on config compatibility between the system and vendored version).

Agreed with what you said. I'm just wondering if Pulp wouldn't always run on Redhat/Fedora systems which will use the system configured openssl...? So the question is whether anyone uses PySequoia with the Rust backend and still needs crypto policies (so this sounds like a RedHat/Fedora system but with pysequoia from pypi).

As far as the feature flag goes, that's more a question for @michaelkuhn. I can also ask a coworker who deals with packaging more than I do.

Please do. I'm wondering if we could just always use system policy on RedHat/Fedora and Standard otherwise (please correct me if there's a use-case I don't see here).

No worries, I understand. There is already a workaround in place so it's not so time sensitive as to cause a rush

Thanks for your understanding! I'm trying to keep the library small and cohesive as it's super-easy to support every use case and then end up looking like GnuPG (no offence 😅 ).

@dralley

dralley commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

Agreed with what you said. I'm just wondering if Pulp wouldn't always run on Redhat/Fedora systems which will use the system configured openssl...?

Some users use a container image which is built from PyPI packages, other users consume the RPMs built by @Odilhao or use containers built from those RPMs. The sort of user that cares about OpenSSL hardening is usually going to be using the RPMs though.

So the question is whether anyone uses PySequoia with the Rust backend and still needs crypto policies (so this sounds like a RedHat/Fedora system but with pysequoia from pypi).

In this particular case, yes.

Thanks for your understanding! I'm trying to keep the library small and cohesive as it's super-easy to support every use case and then end up looking like GnuPG (no offence 😅 ).

I get it! Do you want to keep or drop the signature hash option commit?

@Odilhao

Odilhao commented Oct 15, 2026

Copy link
Copy Markdown

For PyPI builds, none of this is really relevant, since I don't think they could use OpenSSL any time soon given pypi/manylinux builds include their own copy of OpenSSL which is too old to enable PQC. The Rust backend is the only real option there and even if they could use OpenSSL, I don't think that the vendored OpenSSL actually respects the system configuration without manual intervention (I think you can set some environment variables or something, but I'm sure that also comes with caveats on config compatibility between the system and vendored version).

Agreed with what you said. I'm just wondering if Pulp wouldn't always run on Redhat/Fedora systems which will use the system configured openssl...? So the question is whether anyone uses PySequoia with the Rust backend and still needs crypto policies (so this sounds like a RedHat/Fedora system but with pysequoia from pypi).

On Foreman we are building PySequoia RPMs with vendored crates and now our containers are built using this rpm, we need the container that is built using the rpm to be able to extends the crypto policy from the base OS, our users sometimes are using hardened crypto policies to meet certifications or regulations requirements. This is also true for a pure RPM installation or a pypi installation, being able to extend the base OS/Container crypto configuration w/o needing to patch the pyproject.toml or any build file would be dope.

@wiktor-k

Copy link
Copy Markdown
Owner

Hmm... okay, what about this minimalistic approach:

  • rename Policy.standard() to Policy.default() - it's not a standard really, but it's a default we've been using
  • add a way to use custom policies to other places that have it (e.g. these from_file readers) so that nothing relies only on StandardPolicy with no way to override
  • merge these two config readers into Policy.from_sequoia_config_file and that could accept an Option<PathBuf> if it's set it reads from a named file, if not it checks the env variable and falls back to the system file
  • drop HashSecurity and other features, I'd rather see something readable like Policy.accept_hash_for_certifications than that collision resistance wording, sadly there's no such a function on that Sequoia API so let's just drop it

And I guess that'd leave the door open for configurable policies (via the config file) while leaving out as many sequoisms as possible.

Yeah, I know it's called pysequoia but I really would like to keep it vendor neutral as possible (that config file would be an exception).

We can evolve that API in the future but I guess this would already solve your use case...?

@dralley

dralley commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

@wiktor-k So, basically, you'd like to remove the from-code configurability and just retain the from-config-file functionality?

merge these two config readers

Policy.from_system_config() is one, but what's the other? Are you talking about openssl or..?

edit: The Tsk/Cert readers?

@dralley
dralley marked this pull request as draft October 16, 2026 14:01
@dralley

dralley commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

I've added a feature flag to automatically respect the system config if present. Let me know if that's not what was intended.

Presumably we still want one for openssl or to include openssl in that, but I'm actually not 100% sure that sequoia itself uses a context which picks up the openssl policy by default. Need to check that. I will ask Neal W.

This is all WIP now, I'm going to clean up the new commits, they are very "first draft" at the moment.

@wiktor-k

Copy link
Copy Markdown
Owner

FWIW I've skimmed the code and it looks good to me 👍 ping me when the cleanups are done and we can do the final round of reviews. Thanks a lot! 👋

@michaelkuhn

Copy link
Copy Markdown

Additional question (maybe @michaelkuhn can help here?) - if redhat systems already use openssl backend would it imply that the system policy is already being enforced on the openssl level?

I'm also not an expert on Rust packaging, but that's how I understood it. The rust-openssl package has been patched to use the system policy by default: https://src.fedoraproject.org/rpms/rust-openssl/blob/rawhide/f/0001-set-PROFILE-SYSTEM-as-default-cipher-list.patch

@dralley
dralley force-pushed the main branch 5 times, most recently from 32ff264 to e68550a Compare October 19, 2026 15:32
@dralley
dralley marked this pull request as ready for review October 19, 2026 15:33
@dralley
dralley force-pushed the main branch 2 times, most recently from 3fac6b5 to d159019 Compare October 19, 2026 16:45
@dralley

dralley commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

@wiktor-k Ready to be reviewed

@dralley
dralley requested a review from wiktor-k October 19, 2026 16:46
Provide functions for parsing sequoia config files using the
sequoia-policy-config crate.

Expose Policy with .default() and .from_sequoia_config_file()
constructors. Accept a policy on functions which make use of it.

Assisted-By: Codex 5.6 Terra
Signed-off-by: Daniel Alley <dalley@redhat.com>
Assisted-by: Codex GPT-6
Signed-off-by: Daniel Alley <dalley@redhat.com>
Comment thread NEXT.md
This is a step towards a future of non-software keys, where the signer or decryptor may live in an HSM.

More details are available in the [issue comment](https://github.com/wiktor-k/pysequoia/pull/79#issuecomment-5327913731).
v0.1.36

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Maybe I asked this before, but why not just keep a running changelog?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I use that file to fill in tag description but maybe a running file would be a better idea. We would have to pre-fill it from tags in a separate PR.

@wiktor-k wiktor-k left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Okay looks really nice!

Comment thread src/cert/secret.rs Outdated
Comment thread src/policy.rs Outdated
Comment thread src/policy.rs
}
Ok(Self::from_configured_policy(policy))
}
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I'm not sure what can be extracted from the ConfiguredStandardPolicy but it'd be good to print a repr with at least a path of the policy used (or some indication that it's a default policy). This could be useful when debugging problems down the line.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't love the code for this, but it can be done. Let me know if you think the patch is worth it

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Indeed it looks weird. But maybe it's an acceptable trade-off? Let's keep it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ok. Anything else then? Do you want this squashed into the first commit

Comment thread NEXT.md
This is a step towards a future of non-software keys, where the signer or decryptor may live in an HSM.

More details are available in the [issue comment](https://github.com/wiktor-k/pysequoia/pull/79#issuecomment-5327913731).
v0.1.36

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I use that file to fill in tag description but maybe a running file would be a better idea. We would have to pre-fill it from tags in a separate PR.

Comment thread README.md Outdated
Comment thread README.md Outdated
Show policy sources in repr
Clarify policy usage
Move policy details into dedicated documentation.

Assisted-by: Codex GPT-6
Signed-off-by: Daniel Alley <dalley@redhat.com>
@dralley

dralley commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

@wiktor-k New commit w/ feedback addressed.

This branch has not been deployed

No deployments
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