Skip to content

feat: add artifact signing behind experimental build tag - #1044

Draft
matthyx wants to merge 11 commits into
kubescape:mainfrom
matthyx:upstream/experimental-signing
Draft

matthyx wants to merge 11 commits into
kubescape:mainfrom
matthyx:upstream/experimental-signing

Conversation

@matthyx

@matthyx matthyx commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Adds opt-in artifact signing behind the experimental_signing Go build tag. Normal builds retain the baseline implementations and exclude the new signing packages. Build with make binary BUILD_TAGS=experimental_signing or pass the same build argument to the Docker build.

The experimental build supports signed ContainerProfile bundles, Rules and rule bindings; root-signed trust policies with guarded reload; signed config and clusterData; /policyz; and the sign-object CLI. Profile verification runs before grouped-section flattening, restores verified embedded content, rejects malformed embedded specs in either mode, and retries refused profiles after re-signing. Bundle assembly explicitly rejects grouped fragments; standalone grouped profiles remain supported. Binding selectors and rules come from authenticated signed content.

This ports the signing feature from https://github.com/entlein/node-agent/pull/122 independently of https://github.com/entlein/node-agent/pull/121. It does not add RogueArtifact persistence, governance classification, or R1017 emission. R1016 handles tampering, R1018 reports unsigned governing profiles, and stored-spec divergence remains diagnostic.

Validation

Passed locally after rebasing onto upstream c7a77c13 (Go 1.27):

  • Targeted config, health, cache, rule admission/binding/creator/types, storage, and signing tests in both applicable build variants.
  • Agent builds with and without the tag; signing CLI build.
  • Vet for the affected packages in both variants.
  • Race tests for the experimental profile cache, rule binding cache, rule creator, and rules watcher.
  • Default dependency graph excludes the experimental signing packages, Cosign, and Fulcio.

Adds CI coverage for both variants and build-isolation checks. Docker images and cluster/component tests have not been run.

Integration and limitations

Rebased onto current upstream c7a77c13. The branch contains the experimental signing implementation and its regression fixes; fork-only CI commits are excluded. The rebase preserves upstream host-sensor validation, dependency versions, canonical rule schemas, and watcher validation. It reuses upstream compact YAML and profile-list methods instead of adding duplicates. A regression test covers alert-to-enforce policy reload when upstream's checksum fetch optimization is active.

Flat profiles retain the legacy verification behavior, which accepts self-signed certificates and detects content changes without bundle-class signer authorization. Signed bundles with a real trust root are required when signer authorization is needed. Invalid boot trust policies leave signing disabled until a valid policy is loaded; rejected reloads retain the in-force policy. Existing bindings are re-evaluated on their next binding event.

@coderabbitai

coderabbitai Bot commented Oct 22, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
@matthyx
matthyx force-pushed the upstream/experimental-signing branch from eca5bd5 to 292ec45 Compare October 22, 2026 16:18
@matthyx
matthyx requested a balanced review from Copilot October 22, 2026 16:33
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Authenticated binding content is not consistently used for enforcement, and unresolved assembly, re-signing, and status defects affect correctness.

4 open issues
What changed in this PR

Adds opt-in artifact signing to node-agent behind experimental_signing, while preserving default-build behavior and excluding signing dependencies from normal builds.

Changes:

  • Introduces signature verification, bundle assembly, trust-policy handling, and signed configuration support.
  • Integrates profile and rule admission with cache reconciliation and /policyz status reporting.
  • Adds signing fixtures, regression tests, build-tag support, CI checks, and documentation.
File Description
tests/​resources/​signed/​trust-policy.signed.json Signed profile and rule trust policy.
tests/​resources/​signed/​trust-policy.profiles-only.signed.json Signed profile-only policy.
tests/​resources/​signed/​trust-policy.profiles-only.json Profile-only policy source.
tests/​resources/​signed/​trust-policy.json Profile and rule policy source.
tests/​resources/​signed/​trust-policy.enforce.signed.json Enforce-mode policy fixture.
tests/​resources/​signed/​trust-policy.badsigner.signed.json Unauthorized policy-signer fixture.
tests/​resources/​signed/​rules/​untrusted-signer.yaml Untrusted rule source fixture.
tests/​resources/​signed/​rules/​untrusted-signer-signed.yaml Signed untrusted-rule fixture.
tests/​resources/​signed/​rules/​namespace-override.yaml Bundle-scoped rule overlay source.
tests/​resources/​signed/​rules/​namespace-override-v2.yaml Revised rule overlay source.
tests/​resources/​signed/​rules/​namespace-override-v2-signed.yaml Signed revised rule overlay.
tests/​resources/​signed/​rules/​namespace-override-signed.yaml Signed rule overlay fixture.
tests/​resources/​signed/​rules/​mixed-overlay-rejected.yaml Mixed rule-allowlist rejection fixture.
tests/​resources/​signed/​keys/​ct-vendor.pem Vendor signing test key.
tests/​resources/​signed/​keys/​ct-untrusted.pem Untrusted signing test key.
tests/​resources/​signed/​keys/​ct-root.pem Root signing test key.
tests/​resources/​signed/​keys/​ct-operator.pem Operator signing test key.
tests/​resources/​signed/​keys/​ct-nonroot.pem Non-root signing test key.
tests/​resources/​signed/​fragments/​masq-baseline.yaml Baseline ingress fragment source.
tests/​resources/​signed/​fragments/​masq-baseline-signed.yaml Signed baseline ingress fragment.
tests/​resources/​signed/​fragments/​masq-base.yaml Base process-profile source.
tests/​resources/​signed/​fragments/​masq-base-signed.yaml Signed base process profile.
tests/​resources/​signed/​fragments/​masq-admission.yaml Admission fragment source.
tests/​resources/​signed/​fragments/​masq-admission-vendorkey-signed.yaml Wrong-class signer fixture.
tests/​resources/​signed/​fragments/​masq-admission-untrusted-signed.yaml Untrusted admission-signer fixture.
tests/​resources/​signed/​fragments/​masq-admission-operator-signed.yaml Authorized admission-signer fixture.
tests/​resources/​signed/​fragments/​bundle56-overlay-v3.yaml Version-three overlay source.
tests/​resources/​signed/​fragments/​bundle56-overlay-v3-signed.yaml Signed version-three overlay.
tests/​resources/​signed/​fragments/​bundle56-overlay-v2.yaml Version-two overlay source.
tests/​resources/​signed/​fragments/​bundle56-overlay-v2-signed.yaml Signed version-two overlay.
tests/​resources/​signed/​fragments/​bundle56-overlay-v1.yaml Version-one overlay source.
tests/​resources/​signed/​fragments/​bundle56-overlay-v1-signed.yaml Signed version-one overlay.
tests/​resources/​signed/​fragments/​bundle56-base.yaml Versioned bundle base source.
tests/​resources/​signed/​fragments/​bundle56-base-signed.yaml Signed versioned bundle base.
tests/​resources/​signed/​fragments/​bundle37-overlay.yaml Execution overlay source.
tests/​resources/​signed/​fragments/​bundle37-overlay-v3.yaml Expanded version-three overlay.
tests/​resources/​signed/​fragments/​bundle37-overlay-v3-signed.yaml Signed expanded overlay.
tests/​resources/​signed/​fragments/​bundle37-overlay-v2.yaml Version-two execution overlay.
tests/​resources/​signed/​fragments/​bundle37-overlay-v2-signed.yaml Signed version-two execution overlay.
tests/​resources/​signed/​fragments/​bundle37-overlay-signed.yaml Signed execution overlay.
tests/​resources/​signed/​fragments/​bundle37-base.yaml Base execution-profile source.
tests/​resources/​signed/​fragments/​bundle37-base-signed.yaml Signed base execution profile.
tests/​resources/​signed/​fragments/​bundle37-admission.yaml Network admission source.
tests/​resources/​signed/​fragments/​bundle37-admission-signed.yaml Signed network admission fragment.
tests/​resources/​signed/​ct-root.pub Test root verification key.
README.md Uses package-level build and debug targets.
pkg/​signature/​verify.go Verifies stored or embedded signed content.
pkg/​signature/​verifier.go Provides verifier wrappers.
pkg/​signature/​signer.go Provides the signer wrapper.
pkg/​signature/​sign.go Signs objects and embeds content.
pkg/​signature/​profiles/​seccompprofile_adapter.go Adapts seccomp profiles for signing.
pkg/​signature/​profiles/​rules_adapter.go Defines signed rule content.
pkg/​signature/​profiles/​empty_typemeta_test.go Tests type-metadata defaults.
pkg/​signature/​profiles/​containerprofile_adapter.go Defines signed ContainerProfile content.
pkg/​signature/​profiles/​binding_adapter.go Adapts rule bindings for signing.
pkg/​signature/​interface.go Defines signing interfaces and options.
pkg/​signature/​hash.go Exposes canonical content hashing.
pkg/​signature/​embedded.go Encodes and bounds embedded payloads.
pkg/​signature/​cosign_adapter_test.go Tests signing adapters and errors.
pkg/​signature/​cluster_scenario_test.go Tests signing with missing type metadata.
pkg/​signature/​bundle/​status.go Tracks policy identity and counters.
pkg/​signature/​bundle/​status_test.go Tests policy-status lifecycle.
pkg/​signature/​bundle/​signer_identity_test.go Tests public-key signer identity.
pkg/​signature/​bundle/​root.go Resolves root-key fingerprints.
pkg/​signature/​bundle/​root_mounted_test.go Tests mounted root verification.
pkg/​signature/​bundle/​reload_d16_test.go Tests reload guard helpers.
pkg/​signature/​bundle/​reload_d16_poll_test.go Tests guarded policy reloads.
pkg/​signature/​bundle/​pair_fixture_test.go Tests execution grants from signed fixtures.
pkg/​signature/​bundle/​mode_test.go Tests policy modes and root guards.
pkg/​signature/​bundle/​merkle.go Computes bundle Merkle roots.
pkg/​signature/​bundle/​loaders.go Loads policies against trusted roots.
pkg/​signature/​bundle/​binding.go Authorizes signed rule bindings.
pkg/​signature/​bundle/​assemble.go Merges verified fragment specs.
pkg/​signature/​annotations.go Defines signature annotations and errors.
pkg/​rulemanager/​types/​v1/​types.go Restricts baseline types to default builds.
pkg/​rulemanager/​types/​v1/​types_signing.go Adds runtime rule provenance.
pkg/​rulemanager/​types/​v1/​profiledata_signing_test.go Tests signed-payload null compatibility.
pkg/​rulemanager/​ruleswatcher/​watcher.go Restricts baseline watcher to default builds.
pkg/​rulemanager/​ruleswatcher/​admission.go Filters and scopes admitted rules.
pkg/​rulemanager/​rulecreator/​ruleengine_mock.go Restricts baseline mock to default builds.
pkg/​rulemanager/​rulecreator/​ruleengine_mock_signing.go Adds signing-aware rule mock.
pkg/​rulemanager/​rulecreator/​ruleengine_interface.go Restricts baseline interface to default builds.
pkg/​rulemanager/​rulecreator/​ruleengine_interface_signing.go Exposes multi-variant rule lookups.
pkg/​rulemanager/​rulecreator/​factory.go Restricts baseline factory to default builds.
pkg/​rulebindingmanager/​cache/​mock.go Restricts baseline cache mock.
pkg/​rulebindingmanager/​cache/​mock_signing.go Initializes signing-aware cache mock.
pkg/​rulebindingmanager/​cache/​cache.go Restricts baseline binding cache.
pkg/​objectcache/​containerprofilecache/​unsigned_key_test.go Tests stable unsigned-alert keys.
pkg/​objectcache/​containerprofilecache/​spec_divergence_test.go Tests diagnostic deduplication.
pkg/​objectcache/​containerprofilecache/​spec_divergence_signing.go Reports stored-spec divergence.
pkg/​objectcache/​containerprofilecache/​signing_integration_test.go Tests policy reload, refusal, and recovery.
pkg/​objectcache/​containerprofilecache/​signing_enabled.go Adds signing state and admission hooks.
pkg/​objectcache/​containerprofilecache/​signing_disabled.go Provides default-build no-op hooks.
pkg/​objectcache/​containerprofilecache/​rollback_guard_test.go Tests fragment rollback protection.
pkg/​objectcache/​containerprofilecache/​reconciler.go Integrates signing into refresh admission.
pkg/​objectcache/​containerprofilecache/​grouped_signature_test.go Tests verification before flattening.
pkg/​objectcache/​containerprofilecache/​embedded_decode_signing_test.go Tests malformed embedded-spec refusal.
pkg/​objectcache/​containerprofilecache/​containerprofilecache.go Integrates signing into cache population.
pkg/​objectcache/​containerprofilecache/​bundle_policy_race_test.go Exercises concurrent policy access.
pkg/​objectcache/​containerprofilecache/​bundle_fragment_cap_test.go Tests bundle fragment limits.
pkg/​healthmanager/​policyz_test.go Tests policy-status HTTP responses.
pkg/​healthmanager/​health_signing.go Implements experimental /policyz.
pkg/​healthmanager/​health_manager.go Registers build-specific health routes.
pkg/​healthmanager/​health_default.go Omits policy routes in default builds.
pkg/​config/​config.go Adds signing options and loading hook.
pkg/​config/​config_signing.go Loads verified signed configuration.
pkg/​config/​config_signing_test.go Tests invalid signed-config rejection.
pkg/​config/​config_default.go Preserves baseline configuration loading.
pkg/​config/​config_default_test.go Tests default-build signing isolation.
Makefile Passes optional build tags.
docs/​features/​experimental-signing.md Documents usage and limitations.
cmd/​signing_default.go Supplies baseline startup helpers.
cmd/​sign-object/​entrypoint.sh Uses mounted-directory ownership for CLI execution.
cmd/​sign-object/​Dockerfile Packages the signing CLI.
cmd/​main.go Wires signing startup and configuration.
build/​Dockerfile.debug Supports tagged package builds.
build/​Dockerfile Supports optional signing builds.
.github/​workflows/​experimental-signing.yaml Tests both variants and dependency isolation.

Review effort: Balanced

Comment thread pkg/signature/bundle/assemble.go
Comment thread pkg/signature/bundle/binding.go
Comment thread pkg/signature/bundle/status.go Outdated
Comment thread pkg/signature/sign.go Outdated
Enforce authenticated binding specs, reject unsupported grouped bundle fragments, preserve absent policy status, and clear stale embedded content on re-signing.

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved verification and reconciliation issues can bypass intended signing guarantees or retain unsigned enforcement content.

3 open issues
3 previously missed issues

In code that hasn't changed since last review

Medium severity Bind bundle trust policy path environment variable

pkg/​config/​config_signing.go:35

When bundleTrustPolicyPath is absent from the JSON file, setting only BUNDLETRUSTPOLICYPATH does not populate the field: AutomaticEnv does not register keys for viper.Unmarshal, and this key has neither a default nor an explicit binding. Consequently, configureSigning sees an empty path and never starts trust-policy loading or reload. Register the key alongside the verification flag and add an environment-only configuration test.

Medium severity Use original pod label for bundle profile lookup

pkg/​objectcache/​containerprofilecache/​reconciler.go:496

UserCPRef.Name can be <label>-<containerName> because initial population records the resolved per-container profile name. If a signed bundle named <label> becomes available later, including after policy reload, refresh searches for <label>-<containerName> instead and continues using the standalone profile. Newly started containers resolve the original pod label to the bundle, so enforcement differs by container age. Use the original pod label for bundle lookup and retain UserCPRef for the standalone-profile fallback.

Medium severity Delay unsigned profile alert until section resolution

pkg/​objectcache/​containerprofilecache/​signing_enabled.go:44

This emits R1018 before either caller runs resolveAuthoredSection. An unsigned grouped document with no section for this container, or a label-referenced learned profile, is subsequently discarded by that resolver but has already produced an “Unsigned profile governs” alert and consumed its deduplication key. Notify only after successful section resolution and adoption, in both initial population and refresh.

4 resolved since last review

Review effort: Balanced

Comment thread pkg/objectcache/containerprofilecache/reconciler.go Outdated
Comment thread pkg/signature/bundle/loaders.go Outdated
Comment thread pkg/signature/embedded.go
Track verified bundle policy provenance, fail closed on trust-root probe errors, and bind embedded namespaces when signed.

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-sensitive trust and admission changes need human review, particularly the unresolved enforcement behavior during source-fetch failures.

1 open issue
2 previously missed issues

In code that hasn't changed since last review

Medium severity Preserve original pod labels for bundle discovery

pkg/​objectcache/​containerprofilecache/​reconciler.go:496

When initial population resolves a per-container profile (for example, pod label bundle37 resolves to bundle37-app), UserCPRef.Name stores the resolved profile name. Refresh therefore searches for bundle bundle37-app, while initial population searches for bundle37. Installing a valid bundle37 bundle later leaves existing containers on the flat profile, including after a policy reload. Preserve the original pod label separately for bundle discovery, keep UserCPRef for flat-profile fetches, and add a per-container flat-to-bundle transition test.

Medium severity Report unsigned profiles only after successful adoption

pkg/​objectcache/​containerprofilecache/​signing_enabled.go:61

In non-enforcing mode, this emits R1018 before the caller decides whether the profile can govern the container. An unsigned grouped document without a matching container section is reported here, then discarded by resolveAuthoredSection; a document carrying a learning-status annotation is also reported and discarded. These produce an "Unsigned profile governs" alert for content that was never adopted. Carry the unsigned verdict to the population and refresh callers, and notify only after resolution and adoption succeed. Add tests for both rejected-profile cases.

3 resolved since last review

Review effort: Balanced

Comment thread pkg/objectcache/containerprofilecache/reconciler.go
Gate cached content retention on signing eligibility, retain original bundle labels and flat retry references, and emit unsigned-governs alerts only after adoption.

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The cross-cutting trust and admission changes require human security review and deployment validation in addition to resolving the retained findings.

No open issues 🎉

2 previously missed issues

In code that hasn't changed since last review

Medium severity Bypass fast path after refusal with empty authored ResourceVersion

pkg/​objectcache/​containerprofilecache/​signing_enabled.go:109

Refusal rebuilds the entry with empty RV, UserCPRV, and checksum values, but records the current projection-spec hash. If the learned source is absent and the authored profile has an empty ResourceVersion, successfully re-signing that profile still satisfies every fast-skip condition in refreshOneEntry (lines 571–577). Verification succeeds and the entry is marked verified, but its empty projection is never replaced. Remote profiles may legitimately have empty ResourceVersions. Track refusal explicitly and bypass the unchanged-source fast path until admitted content has been projected; add a recovery regression with an absent learned source and an empty authored ResourceVersion.

Medium severity Log unchanged bundle verification successes at Debug

pkg/​signature/​verify.go:104

This emits an Info record on every successful verification, including unchanged bundle fragments. The reconciler reassembles bundles for each cached container, so 100 containers using a 64-fragment bundle can produce 6,400 success records per refresh, even when nothing changes. This adds sustained log serialization and ingestion costs despite the bundle layer already logging root changes at Info. Log individual verification successes at Debug instead.

1 resolved since last review

Review effort: Balanced

Rebuild refused profiles before accepting unchanged empty resource versions and log routine verification successes at debug level.

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
@matthyx

matthyx commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Addressed both additional findings in review 5618240835 in a397eb4:

  • Refused entries bypass unchanged-source shortcuts until admitted content is projected. A regression reproduces absent learned data plus an authored profile with empty ResourceVersion, then checks that re-signing restores execution grants, completed state, and stable subsequent refreshes.
  • Individual verification successes now log at Debug; bundle root transitions remain visible at Info. The existing logging test was updated to preserve diagnostic-field coverage.

Affected tests, race tests, vet, default checks, and the experimental agent build pass locally.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Unresolved verification and policy-publication issues, combined with unvalidated end-to-end enforcement behavior, require fixes and final human review.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Prevent stale policy sync from overwriting reloaded rules

pkg/​rulemanager/​ruleswatcher/​admission.go:67

The policy passed to admission can become stale before the result is published. In watcher_signing.go, trustPolicySnapshot releases policyMutex before admission and SyncRules. Meanwhile, the reload goroutine calls SetTrustPolicy and ResyncNow. A watch-triggered sync using the old policy can finish after the reload's resync and overwrite the new ruleset, restoring rules the new policy rejects—or unsigned rules if signing was previously disabled. These remain active until another sync. Coordinate policy replacement with admission and publication, or atomically validate a policy generation at publication and retry stale results. Add a regression that pauses an old sync and resumes it after reload completes.

Review effort: Balanced

Comment thread pkg/signature/embedded.go
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-sensitive trust and admission changes need final human validation across both build variants, with unresolved correctness issues still requiring fixes.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Register bundle trust policy path for environment-only configuration

pkg/​config/​config_signing.go:35

Register bundleTrustPolicyPath with Viper, for example with an empty-string default. AutomaticEnv() does not include otherwise unknown environment-only keys in Unmarshal, so setting BUNDLETRUSTPOLICYPATH without that key in the configuration file leaves cfg.BundleTrustPolicyPath empty. configureSigning then skips policy loading and the reload watcher, leaving policy-driven profile, rule, and binding signing disabled. Add a regression that loads the policy path from the environment alone.

1 resolved since last review

Review effort: Balanced

Comment thread pkg/objectcache/containerprofilecache/signing_enabled.go Outdated
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
@matthyx
matthyx requested a balanced review from Copilot October 22, 2026 18:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Cross-cutting trust changes, unresolved validation and tamper-reporting issues, and outstanding cluster validation require final human security review.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment thread pkg/rulemanager/ruleswatcher/admission.go
Comment thread pkg/signature/verify.go
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-sensitive trust and admission changes need human review, with unresolved correctness issues and Docker and cluster validation still outstanding.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Reject oversized embedded content before signing

pkg/​signature/​sign.go:48

With embedding enabled, SignObject can report success for content its verifier always rejects: decodeEmbeddedContent caps decompressed content at 8 MiB, but this path and the encoder impose no matching limit. Compression can make an oversized payload fit in a small annotation, so compressed size does not prevent this mismatch. Reject marshaled content above maxEmbeddedContentBytes here, before signing or modifying annotations. Add boundary tests for exactly the limit and one byte above it.

2 resolved since last review

Review effort: Balanced

Comment thread pkg/config/config_signing.go Outdated
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-sensitive trust and admission changes need final human review, and the retained artifact-size validation issue remains unresolved.

1 open issue
1 resolved since last review

Review effort: Balanced

Comment thread pkg/signature/sign.go Outdated
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-sensitive trust, admission, and concurrent enforcement changes need human sign-off, with Docker and cluster integration validation still outstanding.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

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

Status: WIP

Development

Successfully merging this pull request may close these issues.

2 participants