Skip to content

feat: split cose and jwt into independent default-on features#56

Closed
imlk0 wants to merge 1 commit into
veraison:mainfrom
inclavare-containers:feature-guard
Closed

feat: split cose and jwt into independent default-on features#56
imlk0 wants to merge 1 commit into
veraison:mainfrom
inclavare-containers:feature-guard

Conversation

@imlk0

@imlk0 imlk0 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Split COSE and JWT into two independent, default-on cargo features, and stop cose from implying jwt. Previously the three dependencies (cose-rust, openssl, jsonwebtoken) were unconditional, and cose implied jwt — so JWT-only builds could not drop
cose-rust + openssl, and the two features were not orthogonal.

Motivation

EAR tokens can be serialized as either JWT or COSE, and the two are independent at the protocol level. In the original implementation, however:

  • cose-rust / openssl / jsonwebtoken were all unconditional dependencies;
  • the cose feature implied the jwt feature — because from_cose_jwk reuses the jsonwebtoken crate's jwk module to parse the JWK verification key.

That was a convenience reuse, not a fundamental requirement of COSE. For downstreams that only need JWT (or only COSE), this is unnecessary weight — especially since openssl-sys drags in a full native build.

Changes

  • Cargo.toml

    • cose-rust / openssl / jsonwebtoken marked optional = true.
    • Added features:
      default = ["cose", "jwt"]
      cose = ["dep:cose-rust", "dep:openssl", "dep:jsonwebtoken"]
      jwt  = ["dep:jsonwebtoken"]
    • cose now depends on dep:jsonwebtoken (the crate) rather than the jwt feature. from_cose_jwk still uses jsonwebtoken to parse JWK, but does not pull in the jwt feature's API surface.
  • src/ear.rs

    • Added #[cfg(feature = ...)] to all COSE/JWT items: from_cose_jwk, from_cose, sign_cose_*, new_cose_header, alg_to_cose, and the COSE tests are gated on cose; from_jwt*, sign_jwt_*, new_jwt_header, alg_to_jwt_alg, and the JWT tests on jwt.
    • The shared use jsonwebtoken::{self as jwt, jwk}; is guarded with #[cfg(any(feature = "cose", feature = "jwt"))] so the COSE path can access these shared types without forcing the jwt feature on. No runtime logic was changed.
  • src/lib.rs

    • The new_cose_header / new_jwt_header re-exports are feature-gated.
    • The three crate-level doctests that use JWT APIs are wrapped in # #[cfg(feature = "jwt")] { ... # } so the full feature matrix passes cargo test; the pre-existing shared example is marked ```ignore (requires the cose and jwt features).

Backward compatibility

  • default = ["cose", "jwt"] is unchanged, so out-of-the-box behavior is identical.
  • Zero breakage for downstreams that do not pin features explicitly.
  • Users of --no-default-features now select cose / jwt as needed.

Verification

Build cargo build cargo test (lib) doctests
--no-default-features --features cose 21 passed 5 passed
--no-default-features --features jwt 22 passed 5 passed
default (cose+jwt) 23 passed 5 passed

cargo tree --no-default-features --features cose confirms the cose-only build pulls jsonwebtoken as a direct dependency without compiling the jwt feature's code; the jwt-only build does not pull cose-rust / openssl.

@Xynnn007 Xynnn007 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @imlk0 Thanks for the contribution!
Could you help:

  1. Try to move featured functions into a separate module, and use feature flag on top of that module.
  2. Try to use less feature flags.

@imlk0
imlk0 force-pushed the feature-guard branch 2 times, most recently from 178e58c to 73a6c89 Compare July 14, 2026 08:04
@imlk0
imlk0 requested a review from Xynnn007 July 14, 2026 08:07
Comment thread src/ear/cose.rs
Make cose-rust, openssl, and jsonwebtoken optional behind two
independent default-on features:

  cose = [dep:cose-rust, dep:openssl, dep:jsonwebtoken]
  jwt  = [dep:jsonwebtoken]

cose no longer implies the jwt feature -- it depends on the
jsonwebtoken *crate* (used by from_cose_jwk to parse JWK keys), not the
jwt feature's API surface. This lets JWT-only builds drop cose+openssl
and COSE-only builds drop the jwt feature's code, with the two features
genuinely orthogonal.

The jsonwebtoken import in ear.rs is now gated on any(cose, jwt) so the
shared JWK types are available to the cose path without forcing the jwt
feature on. JWT-only doctests are wrapped in cfg(feature = "jwt")
blocks so the feature matrix (cose-only / jwt-only / default) all pass
cargo test cleanly.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Kun Lai <laikun@linux.alibaba.com>

@Xynnn007 Xynnn007 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. Thanks! @imlk0

@thomas-fossati thomas-fossati left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks!

@inclavare-containers inclavare-containers closed this by deleting the head repository Jul 14, 2026
@imlk0

imlk0 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

I accidentally deleted the branch which closed the PR, but it is now restored with the same commit ac0635f. Could you please take another look at #57?
@thomas-fossati @Xynnn007

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.

4 participants