diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index bb164ad7..5ba08185 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -137,8 +137,7 @@ jobs: if: "!startsWith(github.ref, 'refs/tags/v')" integration-tests: - # if: "!startsWith(github.ref, 'refs/tags/v')" - if: false + if: "!startsWith(github.ref, 'refs/tags/v')" needs: deploy-ec2 runs-on: ubuntu-latest strategy: @@ -220,7 +219,6 @@ jobs: path: ./integration_test/coverage/ report-coverage: - if: false needs: integration-tests runs-on: ubuntu-latest steps: diff --git a/Dockerfile b/Dockerfile index 22b6d350..1bb892d3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-bullseye AS builder +FROM golang:1.24-bullseye AS builder RUN apt-get update && apt-get install ADD . /signatory WORKDIR /signatory diff --git a/README.md b/README.md index e513c053..9c82e4d0 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Explore detailed documentation for various components of Signatory: ### Other - [JWT Authentication](https://signatory.io/docs/jwt) +- [Proof of Possession (POP)](https://signatory.io/docs/proof_of_possession) - [Remote Policy Configuration](https://signatory.io/docs/remote_policy) - [Signatory Architecture](https://signatory.io/docs/architecture) - [Glossary](https://signatory.io/docs/glossary) diff --git a/cmd/commands/utils.go b/cmd/commands/utils.go index c1242b5c..c96de5bb 100644 --- a/cmd/commands/utils.go +++ b/cmd/commands/utils.go @@ -10,13 +10,14 @@ import ( ) const listTemplateSrc = `{{range . -}} -Public Key Hash: {{.Hash}} -Reference: {{keyRef .KeyReference}} -Vault: {{.Vault.Name}} -Active: {{.Active}} +Public Key Hash: {{.Hash}} +Reference: {{keyRef .KeyReference}} +Vault: {{.Vault.Name}} +Active: {{.Active}} {{with .Policy -}} -Allowed Requests: {{.AllowedRequests}} -Allowed Operations: {{.AllowedOps}} +Allowed Requests: {{.AllowedRequests}} +Allowed Operations: {{.AllowedOps}} +Allow Proof of Possession: {{.AllowProofOfPossession}} {{end}} {{end -}} ` diff --git a/docs/proof_of_possession.md b/docs/proof_of_possession.md new file mode 100644 index 00000000..46871ab6 --- /dev/null +++ b/docs/proof_of_possession.md @@ -0,0 +1,436 @@ +--- +id: proof_of_possession +title: Proof of Possession (POP) +sidebar_label: Proof of Possession +--- + +## Overview + +Proof of Possession (POP) is a cryptographic proof that demonstrates ownership of a private key by creating a signature over the public key itself. In Tezos, POP is specifically required for BLS keys (tz4 addresses) during initial key reveal operations and certain key management operations. + +**Important:** POP is disabled by default for all keys and must be explicitly enabled per-key in the configuration. This is a security best practice—POP should only be enabled temporarily during setup operations, then disabled for production signing. + +## When POP is Required + +### Initial BLS Key Reveals +When a tz4 address is used for the first time, the Tezos protocol requires a reveal operation that includes a Proof of Possession. This proves that the entity revealing the key actually controls the private key. + +**Use cases:** +- First transaction from a new tz4 address +- Initial setup of a tz4 baker account + +### Consensus Key Updates +When updating a delegate's consensus key to a tz4 address, POP is required to prove control of the new consensus key. + +**Use cases:** +- Switching from tz1/tz2/tz3 consensus key to tz4 +- Updating to a new tz4 consensus key + +### Companion Key Registration (DAL) +When registering a tz4 companion key for Data Availability Layer (DAL) participation, POP is required. + +**Use cases:** +- Registering a tz4 key as a DAL companion key +- DAL attestation setup + +### BLS Multisig Setup +Some BLS multisig configurations may require POP for each participant key during setup. + +## When POP is NOT Needed + +### Regular Signing Operations +Once a key has been revealed and is in normal operation, POP is not required for: +- Block signing +- Attestations (endorsements) +- Preattestations (preendorsements) +- Regular transactions +- Smart contract interactions +- Delegation operations + +### After Initial Reveal +After successfully completing the initial reveal operation with POP, subsequent operations from the same tz4 address do not require POP. + +### Non-BLS Keys +Keys of type tz1 (Ed25519), tz2 (Secp256k1), and tz3 (P256) never require Proof of Possession. If you attempt to enable POP for these key types, Signatory will log a warning and ignore the setting. + +## POP Lifecycle & Operational Patterns + +### Pattern 1: Initial Setup (Recommended) + +This is the recommended pattern for setting up a new tz4 key for production use: + +**Step 1: Enable POP for reveal** +```yaml +tezos: + tz4JtjLv1AvUdnvXkG9mBBmLgcwVBV2FoPBK: + allow_proof_of_possession: true + allow: + generic: + - reveal +``` + +**Step 2: Perform reveal with octez-client** +```sh +octez-client reveal key for tz4JtjLv1AvUdnvXkG9mBBmLgcwVBV2FoPBK +``` + +**Step 3: Disable POP and configure for production** +```yaml +tezos: + tz4JtjLv1AvUdnvXkG9mBBmLgcwVBV2FoPBK: + allow_proof_of_possession: false # or remove this line + allow: + block: + attestation: + preattestation: + generic: + - transaction + - delegation +``` + +**Step 4: Restart Signatory** +```sh +systemctl restart signatory +``` + +The key is now ready for production signing operations with POP disabled. + +### Pattern 2: Consensus Key Update + +When updating a delegate's consensus key to tz4: + +**Step 1: Configure the new tz4 consensus key** +```yaml +tezos: + # Existing delegate key + tz1LggX2HUdvJ1tF4Fvv8fjsrzLeW4Jr9t2Q: + allow: + generic: + - update_consensus_key + + # New tz4 consensus key + tz4NewConsensusKeyHash: + allow_proof_of_possession: true + allow: + block: + attestation: + preattestation: +``` + +**Step 2: Update consensus key** +```sh +octez-client set consensus key for tz1LggX2HUdvJ1tF4Fvv8fjsrzLeW4Jr9t2Q to tz4NewConsensusKeyHash +``` + +**Step 3: Disable POP after successful update** +```yaml +tezos: + tz4NewConsensusKeyHash: + allow_proof_of_possession: false # Disable after update + allow: + block: + attestation: + preattestation: +``` + +### Pattern 3: DAL Companion Key + +When registering a tz4 companion key for DAL: + +```yaml +tezos: + # Main baker key + tz1BakerAddress: + allow: + block: + attestation: + attestation_with_dal: + generic: + - register_dal_companion + + # DAL companion key (tz4) + tz4CompanionKeyHash: + allow_proof_of_possession: true # Enable for registration + allow: + attestation_with_dal: +``` + +After successful registration, disable POP: + +```yaml + tz4CompanionKeyHash: + allow_proof_of_possession: false + allow: + attestation_with_dal: +``` + +### Pattern 4: Multisig Setup + +For BLS multisig scenarios where multiple keys need POP enabled: + +```yaml +tezos: + # Multisig participant 1 + tz4Participant1Hash: + allow_proof_of_possession: true + allow: + generic: + - transaction # multisig operations + + # Multisig participant 2 + tz4Participant2Hash: + allow_proof_of_possession: true + allow: + generic: + - transaction +``` + +**Note:** Some multisig configurations may require POP to remain enabled permanently. Check your specific multisig contract requirements. + +### Pattern 5: Mixed Deployment + +In production environments with multiple keys at different lifecycle stages: + +```yaml +tezos: + # Production baker - tz4 already revealed + tz4ProductionBaker1: + allow_proof_of_possession: false # POP disabled for production + allow: + block: + attestation: + preattestation: + + # Production baker - tz1 key (POP not applicable) + tz1ProductionBaker2: + allow: + block: + attestation: + preattestation: + + # New key being set up - temporary POP enabled + tz4NewKeyBeingSetup: + allow_proof_of_possession: true # Temporary - will disable after reveal + allow: + generic: + - reveal +``` + +## Security Considerations + +### Why POP is Disabled by Default + +Proof of Possession is disabled by default for several security reasons: + +1. **Principle of Least Privilege:** Keys should only have the minimum necessary permissions for their current operational state. + +2. **Attack Surface Reduction:** Enabling POP exposes an additional signing endpoint that is not needed for normal operations. + +3. **Operational Clarity:** Explicit enablement ensures operators consciously decide when POP is needed, preventing accidental exposure. + +### What Information POP Reveals + +When a Proof of Possession request is served: +- The public key is revealed (if not already public) +- Confirms that Signatory has access to the private key +- Demonstrates the key is currently active and operational + +### Potential Risks + +**Key Enumeration:** +- Enabled POP endpoints can be probed to discover which keys are configured and active +- Attackers could identify high-value signing infrastructure + +**Denial of Service:** +- POP generation consumes computational resources +- Repeated POP requests could be used in DoS attacks +- Some HSM backends may have rate limits or billing implications + +**Configuration Drift:** +- Keys left with POP enabled indefinitely increase attack surface +- Forgotten POP settings can lead to security vulnerabilities + +### Best Practices + +1. **Enable Temporarily:** Only enable POP when needed for specific operations, then disable it immediately after. + +2. **Per-Key Control:** Use per-key configuration rather than global settings. This ensures fine-grained control and reduces the blast radius of misconfigurations. + +3. **Audit Configuration:** Regularly review your Signatory configuration to ensure POP is not enabled unnecessarily. + +4. **Monitoring:** Set up alerts for POP requests in production environments—they should be rare events. + +5. **Documentation:** Document when and why POP was enabled for each key, and track when it was disabled. + +6. **Separation of Duties:** Consider using separate Signatory instances for setup operations (with POP) and production signing (without POP). + +### Why Per-Key Control is Superior + +Signatory implements per-key POP control rather than global control because: + +- **Isolation:** A compromised configuration for one key doesn't affect others +- **Flexibility:** Different keys can be at different lifecycle stages simultaneously +- **Auditability:** Clear configuration shows exactly which keys have POP enabled +- **Safety:** Impossible to accidentally enable POP globally for all production keys +- **Compliance:** Easier to demonstrate security controls in regulated environments + +## Troubleshooting Guide + +### Error: "proof of possession is not allowed" + +**Symptom:** +``` +ERROR Proof of possession is not allowed. Proof of possession is required for key reveals, +consensus key updates, and companion key registration. To enable, set +'allow_proof_of_possession: true' in the config for this key. +``` + +**Cause:** +You're attempting a reveal or key management operation that requires POP, but it's disabled for this key. + +**Solution:** +Add `allow_proof_of_possession: true` to the key's configuration: + +```yaml +tezos: + tz4YourKeyHash: + allow_proof_of_possession: true + allow: + generic: + - reveal # or other operations you need +``` + +Then restart Signatory and retry the operation. + +### Error/Warning: "proof of possession is not supported" + +**Symptoms:** +``` +ERROR proof of possession is not supported +``` +or +``` +WARN proof of possession is not supported for tz1YourKeyHash +``` + +**Cause 1: Non-BLS Key Type** + +POP is only supported for BLS keys (tz4). If you're seeing this error/warning with a tz1, tz2, or tz3 key, POP is not applicable for that key type. + +**Solution:** +Remove `allow_proof_of_possession` from the configuration for non-tz4 keys: + +```yaml +tezos: + tz1YourKeyHash: + # Remove or comment out this line + # allow_proof_of_possession: true + allow: + block: + attestation: +``` + +**Cause 2: Vault Backend Limitation** + +Some vault backends may not support the POP operation for BLS keys. + +**Solution:** +- Check your vault backend's documentation +- Verify the vault backend supports BLS keys and POP signatures +- Consider using a different vault backend that supports POP + +## Integration with Octez + +### octez-client Commands That Trigger POP + +The following `octez-client` commands will trigger POP requests to Signatory for tz4 keys: + +1. **reveal key for \** + - Initial key reveal for a tz4 address + - Requires `allow_proof_of_possession: true` + +2. **set consensus key for \ to \** + - Updates a delegate's consensus key to a tz4 key + - Requires `allow_proof_of_possession: true` for the tz4 key + +3. **register dal companion for \ as \** + - Registers a tz4 companion key for DAL participation + - Requires `allow_proof_of_possession: true` for the tz4 key + +## Configuration Reference + +### YAML Configuration + +```yaml +tezos: + : + allow_proof_of_possession: # Default: false + # ... other policy settings +``` + +### Parameters + +**allow_proof_of_possession** (boolean, optional, default: `false`) +- Controls whether Signatory will respond to Proof of Possession requests for this key +- `true`: POP requests are allowed (required for reveals and key management) +- `false` or omitted: POP requests are denied (production signing mode) +- Only effective for BLS keys (tz4); ignored for other key types + +### Complete Example + +```yaml +server: + address: :6732 + utility_address: :9583 + +vaults: + local_file: + driver: file + config: + file: /etc/signatory/secret.json + +watermark: + driver: file + +tezos: + # Production tz4 baker (POP disabled) + tz4ProductionBaker: + allow_proof_of_possession: false + log_payloads: true + allow: + block: + attestation: + preattestation: + attestation_with_dal: + generic: + - transaction + - delegation + + # New tz4 key being set up (POP temporarily enabled) + tz4NewKey: + allow_proof_of_possession: true + log_payloads: true + allow: + generic: + - reveal + + # Regular tz1 key (POP not applicable) + tz1RegularKey: + log_payloads: true + allow: + block: + attestation: + preattestation: + generic: + - transaction + - reveal + - delegation +``` + +## See Also + +- [Bakers Guide](bakers.md) - Configuration for baker operations +- [Watermarks](watermarks.md) - Preventing double-signing +- [Getting Started](start.md) - Basic Signatory setup +- [CLI Documentation](cli.md) - Command-line tools + diff --git a/docs/start.md b/docs/start.md index 764553d5..d7c893b2 100644 --- a/docs/start.md +++ b/docs/start.md @@ -159,6 +159,12 @@ tezos: - transaction ``` +### Proof of Possession (POP) for BLS Keys + +BLS keys (tz4 addresses) require a Proof of Possession during initial reveal and certain key management operations. POP is disabled by default and must be explicitly enabled per-key when needed. + +For complete information about when POP is required, how to configure it, and security best practices, see the [Proof of Possession](proof_of_possession.md) documentation. + ### Watermark Backend Watermarks are a critical safety feature in Signatory that prevent double-signing operations at the same block level or round. They track the highest level/round that has been signed for each key and operation type, rejecting any requests to sign at or below that level. diff --git a/go.mod b/go.mod index d4325b64..e69109a9 100644 --- a/go.mod +++ b/go.mod @@ -5,25 +5,25 @@ go 1.24.0 toolchain go1.24.1 require ( - cloud.google.com/go/firestore v1.18.0 - cloud.google.com/go/kms v1.22.0 - github.com/aws/aws-sdk-go-v2 v1.39.0 - github.com/aws/aws-sdk-go-v2/config v1.31.7 - github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.10 - github.com/aws/aws-sdk-go-v2/service/dynamodb v1.50.2 - github.com/aws/aws-sdk-go-v2/service/kms v1.45.2 - github.com/aws/smithy-go v1.23.0 + cloud.google.com/go/firestore v1.19.0 + cloud.google.com/go/kms v1.23.2 + github.com/aws/aws-sdk-go-v2 v1.39.3 + github.com/aws/aws-sdk-go-v2/config v1.31.13 + github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.15 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.51.1 + github.com/aws/aws-sdk-go-v2/service/kms v1.46.0 + github.com/aws/smithy-go v1.23.1 github.com/certusone/yubihsm-go v0.3.0 github.com/ecadlabs/go-pkcs11 v0.3.0 github.com/ecadlabs/goblst v1.1.0 github.com/ecadlabs/gotez/v2 v2.3.13 github.com/fxamacker/cbor/v2 v2.9.0 - github.com/go-playground/validator/v10 v10.27.0 + github.com/go-playground/validator/v10 v10.28.0 github.com/google/tink/go v1.7.0 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 - github.com/hashicorp/vault/api v1.20.0 - github.com/hashicorp/vault/api/auth/approle v0.10.0 + github.com/hashicorp/vault/api v1.22.0 + github.com/hashicorp/vault/api/auth/approle v0.11.0 github.com/karalabe/hid v1.0.0 github.com/kr/pretty v0.3.1 github.com/prometheus/client_golang v1.23.2 @@ -31,39 +31,39 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.10.1 github.com/stretchr/testify v1.11.1 - golang.org/x/crypto v0.42.0 + golang.org/x/crypto v0.43.0 golang.org/x/exp v0.0.0-20231127185646-65229373498e - golang.org/x/oauth2 v0.31.0 - google.golang.org/api v0.249.0 + golang.org/x/oauth2 v0.32.0 + google.golang.org/api v0.252.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - cloud.google.com/go v0.122.0 // indirect - cloud.google.com/go/auth v0.16.5 // indirect + cloud.google.com/go v0.123.0 // indirect + cloud.google.com/go/auth v0.17.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.8.0 // indirect - cloud.google.com/go/iam v1.5.2 // indirect - cloud.google.com/go/longrunning v0.6.7 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.11 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.7 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.7 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.7 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.30.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.29.2 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.3 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect + cloud.google.com/go/iam v1.5.3 // indirect + cloud.google.com/go/longrunning v0.7.0 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.17 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.31.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/ecadlabs/pretty v0.0.0-20230412124801-f948fc689a04 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gabriel-vasile/mimetype v1.4.10 // indirect - github.com/go-jose/go-jose/v4 v4.1.2 // indirect + github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/s2a-go v0.1.9 // indirect @@ -84,18 +84,18 @@ require ( github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/otel/metric v1.38.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect golang.org/x/sync v0.17.0 // indirect - golang.org/x/time v0.13.0 // indirect - google.golang.org/genproto v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect + golang.org/x/time v0.14.0 // indirect + google.golang.org/genproto v0.0.0-20251014184007-4626949a642f // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f // indirect ) require ( @@ -111,15 +111,15 @@ require ( github.com/leodido/go-urn v1.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/common v0.67.1 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/spf13/pflag v1.0.10 // indirect - golang.org/x/net v0.44.0 // indirect - golang.org/x/sys v0.36.0 - golang.org/x/term v0.35.0 - golang.org/x/text v0.29.0 // indirect - google.golang.org/grpc v1.75.0 - google.golang.org/protobuf v1.36.9 // indirect + golang.org/x/net v0.46.0 // indirect + golang.org/x/sys v0.37.0 + golang.org/x/term v0.36.0 + golang.org/x/text v0.30.0 // indirect + google.golang.org/grpc v1.76.0 + google.golang.org/protobuf v1.36.10 // indirect ) // replace github.com/ecadlabs/gotez/v2 => ../gotez diff --git a/go.sum b/go.sum index 35ca985b..596fb851 100644 --- a/go.sum +++ b/go.sum @@ -1,55 +1,55 @@ -cloud.google.com/go v0.122.0 h1:0JTLGrcSIs3HIGsgVPvTx3cfyFSP/k9CI8vLPHTd6Wc= -cloud.google.com/go v0.122.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= -cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= -cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= +cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= +cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4= +cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA= -cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= -cloud.google.com/go/firestore v1.18.0 h1:cuydCaLS7Vl2SatAeivXyhbhDEIR8BDmtn4egDhIn2s= -cloud.google.com/go/firestore v1.18.0/go.mod h1:5ye0v48PhseZBdcl0qbl3uttu7FIEwEYVaWm0UIEOEU= -cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= -cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= -cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= -cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= -cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= -cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= -github.com/aws/aws-sdk-go-v2 v1.39.0 h1:xm5WV/2L4emMRmMjHFykqiA4M/ra0DJVSWUkDyBjbg4= -github.com/aws/aws-sdk-go-v2 v1.39.0/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= -github.com/aws/aws-sdk-go-v2/config v1.31.7 h1:zS1O6hr6t0nZdBCMFc/c9OyZFyLhXhf/B2IZ9Y0lRQE= -github.com/aws/aws-sdk-go-v2/config v1.31.7/go.mod h1:GpHmi1PQDdL5pP4JaB00pU0ek4EXVcYH7IkjkUadQmM= -github.com/aws/aws-sdk-go-v2/credentials v1.18.11 h1:1Fnb+7Dk96/VYx/uYfzk5sU2V0b0y2RWZROiMZCN/Io= -github.com/aws/aws-sdk-go-v2/credentials v1.18.11/go.mod h1:iuvn9v10dkxU4sDgtTXGWY0MrtkEcmkUmjv4clxhuTc= -github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.10 h1:LYmFi6rVg/Vp5BHqbiYXmve8mcg7qin9OXw8rIad67Y= -github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.10/go.mod h1:WuT2IYv8DDOoRA7jeZW/krRaUDBHoYWDNDgAoULMku0= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.7 h1:Is2tPmieqGS2edBnmOJIbdvOA6Op+rRpaYR60iBAwXM= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.7/go.mod h1:F1i5V5421EGci570yABvpIXgRIBPb5JM+lSkHF6Dq5w= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.7 h1:UCxq0X9O3xrlENdKf1r9eRJoKz/b0AfGkpp3a7FPlhg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.7/go.mod h1:rHRoJUNUASj5Z/0eqI4w32vKvC7atoWR0jC+IkmVH8k= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.7 h1:Y6DTZUn7ZUC4th9FMBbo8LVE+1fyq3ofw+tRwkUd3PY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.7/go.mod h1:x3XE6vMnU9QvHN/Wrx2s44kwzV2o2g5x/siw4ZUJ9g8= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.50.2 h1:oQT34UrvH3ZyaRZsIuoPcplH3O3LDSbRYSEU77RafeI= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.50.2/go.mod h1:lXFSTFpnhgc8Qb/meseIt7+UXPiidZm0DbiDqmPHBTQ= -github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.30.3 h1:PzpsyOIL1x5qavjDqAwaZtHdKvoKG9nFudwGq9suNME= -github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.30.3/go.mod h1:w5NSZOQrrHGt2jCC7tnNzlBWLHZB8xLUcApfiAxsxxM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.7 h1:VN9u746Erhm6xnVSmaUd1Saxs1MVZVum6v2yPOqj8xQ= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.7/go.mod h1:j0BhJWTdVsYsllEfO0E8EXtLToU8U7QeA7Gztxrl/8g= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7 h1:mLgc5QIgOy26qyh5bvW+nDoAppxgn3J2WV3m9ewq7+8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7/go.mod h1:wXb/eQnqt8mDQIQTTmcw58B5mYGxzLGZGK8PWNFZ0BA= -github.com/aws/aws-sdk-go-v2/service/kms v1.45.2 h1:8ZT2x7reXVcZ1WTL1ZhbrtHAZ0FDoUckCOfCY3hj1n4= -github.com/aws/aws-sdk-go-v2/service/kms v1.45.2/go.mod h1:EADaLXofJkof++MP9zhzSZ0byBMOZTIRjtJO/ZMuPVE= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.2 h1:rcoTaYOhGE/zfxE1uR6X5fvj+uKkqeCNRE0rBbiQM34= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.2/go.mod h1:Ql6jE9kyyWI5JHn+61UT/Y5Z0oyVJGmgmJbZD5g4unY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.3 h1:BSIfeFtU9tlSt8vEYS7KzurMoAuYzYPWhcZiMtxVf2M= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.3/go.mod h1:XclEty74bsGBCr1s0VSaA11hQ4ZidK4viWK7rRfO88I= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.3 h1:yEiZ0ztgji2GsCb/6uQSITXcGdtmWMfLRys0jJFiUkc= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.3/go.mod h1:Z+Gd23v97pX9zK97+tX4ppAgqCt3Z2dIXB02CtBncK8= -github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= -github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +cloud.google.com/go/firestore v1.19.0 h1:E3FiRsWfZKwZ6W+Lsp1YqTzZ9H6jP+QsKW40KR21C8I= +cloud.google.com/go/firestore v1.19.0/go.mod h1:jqu4yKdBmDN5srneWzx3HlKrHFWFdlkgjgQ6BKIOFQo= +cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= +cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= +cloud.google.com/go/kms v1.23.2 h1:4IYDQL5hG4L+HzJBhzejUySoUOheh3Lk5YT4PCyyW6k= +cloud.google.com/go/kms v1.23.2/go.mod h1:rZ5kK0I7Kn9W4erhYVoIRPtpizjunlrfU4fUkumUp8g= +cloud.google.com/go/longrunning v0.7.0 h1:FV0+SYF1RIj59gyoWDRi45GiYUMM3K1qO51qoboQT1E= +cloud.google.com/go/longrunning v0.7.0/go.mod h1:ySn2yXmjbK9Ba0zsQqunhDkYi0+9rlXIwnoAf+h+TPY= +github.com/aws/aws-sdk-go-v2 v1.39.3 h1:h7xSsanJ4EQJXG5iuW4UqgP7qBopLpj84mpkNx3wPjM= +github.com/aws/aws-sdk-go-v2 v1.39.3/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM= +github.com/aws/aws-sdk-go-v2/config v1.31.13 h1:wcqQB3B0PgRPUF5ZE/QL1JVOyB0mbPevHFoAMpemR9k= +github.com/aws/aws-sdk-go-v2/config v1.31.13/go.mod h1:ySB5D5ybwqGbT6c3GszZ+u+3KvrlYCUQNo62+hkKOFk= +github.com/aws/aws-sdk-go-v2/credentials v1.18.17 h1:skpEwzN/+H8cdrrtT8y+rvWJGiWWv0DeNAe+4VTf+Vs= +github.com/aws/aws-sdk-go-v2/credentials v1.18.17/go.mod h1:Ed+nXsaYa5uBINovJhcAWkALvXw2ZLk36opcuiSZfJM= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.15 h1:eQW0ilsgVX8za0UX9BeC1G8ZKcT6FXa7I1UpUZ906dU= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.15/go.mod h1:u7tFlbFF4tJ9gw9SpUYzQowTh89wTaJcEjtXXxaS1fI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 h1:UuGVOX48oP4vgQ36oiKmW9RuSeT8jlgQgBFQD+HUiHY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10/go.mod h1:vM/Ini41PzvudT4YkQyE/+WiQJiQ6jzeDyU8pQKwCac= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10 h1:mj/bdWleWEh81DtpdHKkw41IrS+r3uw1J/VQtbwYYp8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10/go.mod h1:7+oEMxAZWP8gZCyjcm9VicI0M61Sx4DJtcGfKYv2yKQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10 h1:wh+/mn57yhUrFtLIxyFPh2RgxgQz/u+Yrf7hiHGHqKY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10/go.mod h1:7zirD+ryp5gitJJ2m1BBux56ai8RIRDykXZrJSp540w= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.51.1 h1:vSxJwz51rdh6AyZnxzZCP76L9HZWGFOEzz0RlfZWyXs= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.51.1/go.mod h1:GyNGZUbiqJH5lMAVNlYlYXCNoJcCmyPAeLxlDKsmi1g= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.31.1 h1:wqHGetHZ0fEhx5IFWitFoijbtdu4HZAAl0452H7ljqE= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.31.1/go.mod h1:IakOzjzwZN+7RAC1Hja1n0A466zBL9lx/I4KIDvJjUY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 h1:xtuxji5CS0JknaXoACOunXOYOQzgfTvGAc9s2QdCJA4= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2/go.mod h1:zxwi0DIR0rcRcgdbl7E2MSOvxDyyXGBlScvBkARFaLQ= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.10 h1:T0QsDQNCVealR4CrVt+spgWJgjl8oIDje/5TH8YnCmE= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.10/go.mod h1:SGBJMtnGk4y9Yvrr3iNPos9WUqexJHxq2OI6Z1ch634= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10 h1:DRND0dkCKtJzCj4Xl4OpVbXZgfttY5q712H9Zj7qc/0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10/go.mod h1:tGGNmJKOTernmR2+VJ0fCzQRurcPZj9ut60Zu5Fi6us= +github.com/aws/aws-sdk-go-v2/service/kms v1.46.0 h1:vSXYridw+tT3AHuK1PWdJto2qEc30/wG/fm8dmCHHis= +github.com/aws/aws-sdk-go-v2/service/kms v1.46.0/go.mod h1:YXPskkMuiMgp6qUG96NSTl7UpideOQT/Kx0u9Y1MKn0= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 h1:fspVFg6qMx0svs40YgRmE7LZXh9VRZvTT35PfdQR6FM= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.7/go.mod h1:BQTKL3uMECaLaUV3Zc2L4Qybv8C6BIXjuu1dOPyxTQs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 h1:scVnW+NLXasGOhy7HhkdT9AGb6kjgW7fJ5xYkUaqHs0= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2/go.mod h1:FRNCY3zTEWZXBKm2h5UBUPvCVDOecTad9KhynDyGBc0= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 h1:VEO5dqFkMsl8QZ2yHsFDJAIZLAkEbaYDB+xdKi0Feic= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.7/go.mod h1:L1xxV3zAdB+qVrVW/pBIrIAnHFWHo6FBbFe4xOGsG/o= +github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= +github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -58,6 +58,8 @@ github.com/certusone/yubihsm-go v0.3.0 h1:mB1m5ZDSqX88xR2Kwq25vGOQKa4SV/polPTRpI github.com/certusone/yubihsm-go v0.3.0/go.mod h1:4TofNVV4saOz2gjxT0xJ1Bt7KuSgMRN5Frhw/OpAb94= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -75,16 +77,21 @@ github.com/ecadlabs/pretty v0.0.0-20230412124801-f948fc689a04 h1:7WdblGykGxtGGtc github.com/ecadlabs/pretty v0.0.0-20230412124801-f948fc689a04/go.mod h1:VApUlocsLMpp4hUXHxTTIlosebnwo0BM6e1hy78qTPM= github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815 h1:D22EM5TeYZJp43hGDx6dUng8mvtyYbB9BnE3+BmJR1Q= github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= -github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI= -github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -96,10 +103,10 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= -github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= -github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= -github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688= +github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= +github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= @@ -141,10 +148,10 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9 github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hashicorp/vault/api v1.20.0 h1:KQMHElgudOsr+IbJgmbjHnCTxEpKs9LnozA1D3nozU4= -github.com/hashicorp/vault/api v1.20.0/go.mod h1:GZ4pcjfzoOWpkJ3ijHNpEoAxKEsBJnVljyTe3jM2Sms= -github.com/hashicorp/vault/api/auth/approle v0.10.0 h1:cFwz7NzhsC//3JMMEfYDKelSwZx7GhR4IdgJVgfKBgs= -github.com/hashicorp/vault/api/auth/approle v0.10.0/go.mod h1:XJ++u6wVPOl7H2Wlb9zVvXungf5Ca1Agukq8rMwYogc= +github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0= +github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM= +github.com/hashicorp/vault/api/auth/approle v0.11.0 h1:ViUvgqoSTqHkMi1L1Rr/LnQ+PWiRaGUBGvx4UPfmKOw= +github.com/hashicorp/vault/api/auth/approle v0.11.0/go.mod h1:v8ZqBRw+GP264ikIw2sEBKF0VT72MEhLWnZqWt3xEG8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/karalabe/hid v1.0.0 h1:+/CIMNXhSU/zIJgnIvBD2nKHxS/bnRHhhs9xBryLpPo= @@ -159,8 +166,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -170,14 +177,16 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= +github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= @@ -201,8 +210,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= @@ -219,47 +228,47 @@ go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJr go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= -golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= -golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= +golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= +golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= -golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.249.0 h1:0VrsWAKzIZi058aeq+I86uIXbNhm9GxSHpbmZ92a38w= -google.golang.org/api v0.249.0/go.mod h1:dGk9qyI0UYPwO/cjt2q06LG/EhUpwZGdAbYF14wHHrQ= -google.golang.org/genproto v0.0.0-20250908214217-97024824d090 h1:ywCL7vA2n3vVHyf+bx1ZV/knaTPRI8GIeKY0MEhEeOc= -google.golang.org/genproto v0.0.0-20250908214217-97024824d090/go.mod h1:zwJI9HzbJJlw2KXy0wX+lmT2JuZoaKK9JC4ppqmxxjk= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 h1:d8Nakh1G+ur7+P3GcMjpRDEkoLUcLW2iU92XVqR+XMQ= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 h1:/OQuEa4YWtDt7uQWHd3q3sUMb+QOLQUg1xa8CEsRv5w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= -google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= -google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/api v0.252.0 h1:xfKJeAJaMwb8OC9fesr369rjciQ704AjU/psjkKURSI= +google.golang.org/api v0.252.0/go.mod h1:dnHOv81x5RAmumZ7BWLShB/u7JZNeyalImxHmtTHxqw= +google.golang.org/genproto v0.0.0-20251014184007-4626949a642f h1:vLd1CJuJOUgV6qijD7KT5Y2ZtC97ll4dxjTUappMnbo= +google.golang.org/genproto v0.0.0-20251014184007-4626949a642f/go.mod h1:PI3KrSadr00yqfv6UDvgZGFsmLqeRIwt8x4p5Oo7CdM= +google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f h1:OiFuztEyBivVKDvguQJYWq1yDcfAHIID/FVrPR4oiI0= +google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f/go.mod h1:kprOiu9Tr0JYyD6DORrc4Hfyk3RFXqkQ3ctHEum3ZbM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f h1:1FTH6cpXFsENbPR5Bu8NQddPSaUUE6NA2XdZdDSAJK4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= +google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/integration_test/signatory-local-secret.json b/integration_test/signatory-local-secret.json index 93b2ee3c..e7f9f2d4 100644 --- a/integration_test/signatory-local-secret.json +++ b/integration_test/signatory-local-secret.json @@ -38,5 +38,9 @@ { "name": "baker1", "value": "unencrypted:edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh" - } + }, + { + "name": "tz4pop", + "value": "unencrypted:BLsk1d6zjtYgWxyZwdnCsQpwYcs3cJRFTMwJ1CWCgjFu4zpaZp9nL6" + } ] diff --git a/integration_test/signatory.default.yaml b/integration_test/signatory.default.yaml index da3c7821..5c585885 100644 --- a/integration_test/signatory.default.yaml +++ b/integration_test/signatory.default.yaml @@ -108,6 +108,14 @@ tezos: generic: - transaction - reveal + allow_proof_of_possession: true + + #tz4pop + tz4Eb1d5L4njHViVgDDkas7qNgoZgDw6VYPz: + log_payloads: true + allow: + generic: + - reveal #speculos tz1RVYaHiobUKXMfJ47F7Rjxx5tu3LC35WSA: diff --git a/integration_test/signatory.yaml b/integration_test/signatory.yaml index da3c7821..5c585885 100644 --- a/integration_test/signatory.yaml +++ b/integration_test/signatory.yaml @@ -108,6 +108,14 @@ tezos: generic: - transaction - reveal + allow_proof_of_possession: true + + #tz4pop + tz4Eb1d5L4njHViVgDDkas7qNgoZgDw6VYPz: + log_payloads: true + allow: + generic: + - reveal #speculos tz1RVYaHiobUKXMfJ47F7Rjxx5tu3LC35WSA: diff --git a/integration_test/tests/config.go b/integration_test/tests/config.go index 0821c2fa..bd87925c 100644 --- a/integration_test/tests/config.go +++ b/integration_test/tests/config.go @@ -1,4 +1,4 @@ -package new_integration_test +package tests import ( "os" @@ -45,9 +45,10 @@ type ServerConfig struct { type TezosConfig = map[string]*TezosPolicy type TezosPolicy struct { - Allow map[string][]string `yaml:"allow"` - LogPayloads bool `yaml:"log_payloads"` - JwtUsers []string `yaml:"jwt_users,omitempty"` + Allow map[string][]string `yaml:"allow"` + LogPayloads bool `yaml:"log_payloads"` + JwtUsers []string `yaml:"jwt_users,omitempty"` + AllowProofOfPossession bool `yaml:"allow_proof_of_possession,omitempty"` } type VaultConfig struct { diff --git a/integration_test/tests/http.go b/integration_test/tests/http.go index de880ee9..cd1af628 100644 --- a/integration_test/tests/http.go +++ b/integration_test/tests/http.go @@ -1,4 +1,4 @@ -package new_integration_test +package tests import ( "bytes" diff --git a/integration_test/tests/keys.go b/integration_test/tests/keys.go index 9e24da38..1c9fa6d2 100644 --- a/integration_test/tests/keys.go +++ b/integration_test/tests/keys.go @@ -1,4 +1,4 @@ -package new_integration_test +package tests // Keys defines all the public key hashes and other keys used in integration tests // This file serves as a centralized reference for all keys used across test files @@ -24,6 +24,8 @@ const ( Tz2AliasPKH = "tz2QPsZoZse4eeahhg5DdfnBDB4VbU1PwgxN" Tz3AliasPKH = "tz3ZbCsUveF3Q6WUNkThT1wyJyhPunanaAXK" Tz4AliasPKH = "tz4XXtsYav3fZz2FSDa7hcx4F8sh8SaDWNME" + + Tz4PopPKH = "tz4Eb1d5L4njHViVgDDkas7qNgoZgDw6VYPz" ) // Public keys corresponding to the public key hashes @@ -39,6 +41,8 @@ const ( Tz2AliasPK = "sppk7cvVVMRRtYTdriTB6KQqpXZt9TUwSTcpMWq4FwpvG2eVZ56UuHP" Tz3AliasPK = "p2pk67wmwXhknDMAtjFJCh1Z65wCemXchB3KYQfDFp2HvDT1S2Z" // Placeholder - needs actual value Tz4AliasPK = "BLpk1nRV5SBB2QCxsiem5Neoywcizr3mkdp167HL1iKFgFvzPhKo4RSy7J8JBh2BgGgVYjNsRGwU" + + Tz4PopPK = "BLpk1w7hcraa8qBo8f7sNBteUVoSejrS779YUra1deGqZgWSw8xUVYrNSMkxWrDAAwTtFtJxvMbK" ) // Secret keys (for reference - these are used in signatory-local-secret.json) @@ -55,6 +59,8 @@ const ( Tz2AliasSK = "unencrypted:spsk1XYsTqUsd7LaLs9a8qpmCvLVJeLEZEXkeAZS5dwcKgUZhv3cYw" Tz3AliasSK = "unencrypted:p2sk2rUMnnnFPQCB7DBozkCZrFhiZ87ddrpAHbRcww7dwU2WHYUbci" Tz4AliasSK = "unencrypted:BLsk1XMDG3iepYGj15mBWc7dYjrkpVVM4VH3y5DyBCN9iAGrELwRbY" + + Tz4PopSK = "unencrypted:BLsk1d6zjtYgWxyZwdnCsQpwYcs3cJRFTMwJ1CWCgjFu4zpaZp9nL6" ) // Authorized keys for authentication tests @@ -77,6 +83,8 @@ const ( Tz2AliasSignatoryURL = "http://signatory:6732/tz2QPsZoZse4eeahhg5DdfnBDB4VbU1PwgxN" Tz3AliasSignatoryURL = "http://signatory:6732/tz3ZbCsUveF3Q6WUNkThT1wyJyhPunanaAXK" Tz4AliasSignatoryURL = "http://signatory:6732/tz4XXtsYav3fZz2FSDa7hcx4F8sh8SaDWNME" + + Tz4PopSignatoryURL = "http://signatory:6732/tz4Eb1d5L4njHViVgDDkas7qNgoZgDw6VYPz" ) // Account aliases used in tests @@ -92,6 +100,7 @@ const ( Tz2Alias = "tz2alias" Tz3Alias = "tz3alias" Tz4Alias = "tz4alias" + Tz4PopAlias = "tz4pop" ) // Structured access to keys using structs @@ -108,6 +117,7 @@ func (PublicKeyHash) Tz1Alias() string { return Tz1AliasPKH } func (PublicKeyHash) Tz2Alias() string { return Tz2AliasPKH } func (PublicKeyHash) Tz3Alias() string { return Tz3AliasPKH } func (PublicKeyHash) Tz4Alias() string { return Tz4AliasPKH } +func (PublicKeyHash) Tz4Pop() string { return Tz4PopPKH } type PublicKey struct{} @@ -119,6 +129,7 @@ func (PublicKey) Tz1Alias() string { return Tz1AliasPK } func (PublicKey) Tz2Alias() string { return Tz2AliasPK } func (PublicKey) Tz3Alias() string { return Tz3AliasPK } func (PublicKey) Tz4Alias() string { return Tz4AliasPK } +func (PublicKey) Tz4Pop() string { return Tz4PopPK } type SecretKey struct{} @@ -131,6 +142,7 @@ func (SecretKey) Tz1Alias() string { return Tz1AliasSK } func (SecretKey) Tz2Alias() string { return Tz2AliasSK } func (SecretKey) Tz3Alias() string { return Tz3AliasSK } func (SecretKey) Tz4Alias() string { return Tz4AliasSK } +func (SecretKey) Tz4Pop() string { return Tz4PopSK } func (SecretKey) Auth() string { return AuthKeySK } type SignatoryURL struct{} @@ -143,6 +155,7 @@ func (SignatoryURL) Tz1Alias() string { return Tz1AliasSignatoryURL } func (SignatoryURL) Tz2Alias() string { return Tz2AliasSignatoryURL } func (SignatoryURL) Tz3Alias() string { return Tz3AliasSignatoryURL } func (SignatoryURL) Tz4Alias() string { return Tz4AliasSignatoryURL } +func (SignatoryURL) Tz4Pop() string { return Tz4PopSignatoryURL } // Global instances for easy access var ( @@ -175,6 +188,8 @@ func GetPKHByAlias(alias string) string { return Tz3AliasPKH case Tz4Alias: return Tz4AliasPKH + case Tz4PopAlias: + return Tz4PopPKH default: return "" } @@ -199,6 +214,8 @@ func GetPKByAlias(alias string) string { return Tz3AliasPK case Tz4Alias: return Tz4AliasPK + case Tz4PopAlias: + return Tz4PopPK default: return "" } @@ -223,6 +240,8 @@ func GetSignatoryURLByAlias(alias string) string { return Tz3AliasSignatoryURL case Tz4Alias: return Tz4AliasSignatoryURL + case Tz4PopAlias: + return Tz4PopSignatoryURL default: return "" } @@ -239,6 +258,7 @@ func GetAllTestPKHs() []string { Tz2AliasPKH, Tz3AliasPKH, Tz4AliasPKH, + Tz4PopPKH, } } @@ -253,5 +273,6 @@ func GetAllTestAliases() []string { Tz2Alias, Tz3Alias, Tz4Alias, + Tz4PopAlias, } } diff --git a/integration_test/tests/metrics.go b/integration_test/tests/metrics.go index 8776ff3e..83225373 100644 --- a/integration_test/tests/metrics.go +++ b/integration_test/tests/metrics.go @@ -1,4 +1,4 @@ -package new_integration_test +package tests import ( "bytes" diff --git a/integration_test/tests/octezclient.go b/integration_test/tests/octezclient.go index 6f1160cd..5d595ec1 100644 --- a/integration_test/tests/octezclient.go +++ b/integration_test/tests/octezclient.go @@ -1,6 +1,9 @@ -package new_integration_test +package tests import ( + "bytes" + "encoding/json" + "fmt" "os/exec" ) @@ -43,3 +46,33 @@ func delete_watermark_files() { panic("Clean tezos: Failed to delete watermarks: " + string(out)) } } + +func GetCurrentProtocol() (string, error) { + out, err := OctezClient("rpc", "get", "/chains/main/blocks/head/metadata") + if err != nil { + return "", err + } + var metadata struct { + Protocol string `json:"protocol"` + } + // Find the line that starts with '{' and parse JSON from that line (Skip warnings) + lines := bytes.Split(out, []byte("\n")) + start := -1 + for i, line := range lines { + line = bytes.TrimSpace(line) + if len(line) > 0 && line[0] == '{' { + start = i + break + } + } + if start == -1 { + return "", fmt.Errorf("no JSON object found in output: %s", string(out)) + } + out = bytes.Join(lines[start:], []byte("\n")) + + if err := json.Unmarshal(out, &metadata); err != nil { + return "", err + } + + return metadata.Protocol, nil +} diff --git a/integration_test/tests/operations/operationkinds_test.go b/integration_test/tests/operations/operationkinds_test.go index 6b2052f1..a902a90b 100644 --- a/integration_test/tests/operations/operationkinds_test.go +++ b/integration_test/tests/operations/operationkinds_test.go @@ -176,7 +176,7 @@ func TestOperationAllowPolicy(t *testing.T) { var c integrationtest.Config c.Read() c.Tezos[test.account].Allow = test.notAllowPolicy - integrationtest.Backup_then_update_config(c) + integrationtest.Update_config(c) defer integrationtest.Restore_config() integrationtest.Restart_signatory() out, err := integrationtest.OctezClient(test.testOp...) diff --git a/integration_test/tests/operations/tz4pop_test.go b/integration_test/tests/operations/tz4pop_test.go new file mode 100644 index 00000000..02e61870 --- /dev/null +++ b/integration_test/tests/operations/tz4pop_test.go @@ -0,0 +1,55 @@ +package operations + +import ( + "strings" + "testing" + + integrationtest "github.com/ecadlabs/signatory/integration_test/tests" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestProofOfPossessionAllowPolicy(t *testing.T) { + defer integrationtest.Clean_tezos_folder() + // policies + var c integrationtest.Config + c.Read() + pkh := integrationtest.PKH.Tz4Pop() + + defer integrationtest.Restore_config() + + protocol, err := integrationtest.GetCurrentProtocol() + assert.NoError(t, err) + + if strings.Compare(protocol, "PtSeouL") >= 0 { // only test this for protocols >= PtSeouL + // Test with allow_proof_of_possession = false (not allowed) + c.Tezos[pkh] = &integrationtest.TezosPolicy{ + Allow: map[string][]string{ + "generic": {"reveal"}, + }, + AllowProofOfPossession: false, + } + integrationtest.Update_config(c) + integrationtest.Restart_signatory() + + out, err := integrationtest.OctezClient("reveal", "key", "for", "tz4pop") + assert.Error(t, err) + require.Contains(t, string(out), "proof of possession is not allowed") + } + + { + // Test with allow_proof_of_possession = true (allowed) + c.Tezos[pkh] = &integrationtest.TezosPolicy{ + Allow: map[string][]string{ + "generic": {"reveal"}, + }, + AllowProofOfPossession: true, + } + integrationtest.Update_config(c) + integrationtest.Restart_signatory() + + out, err := integrationtest.OctezClient("reveal", "key", "for", "tz4pop") + assert.NoError(t, err) + require.Contains(t, string(out), "Operation successfully injected in the node") + } +} diff --git a/integration_test/tests/server/authorizedkeys_test.go b/integration_test/tests/server/authorizedkeys_test.go index 3964b30e..559f2811 100644 --- a/integration_test/tests/server/authorizedkeys_test.go +++ b/integration_test/tests/server/authorizedkeys_test.go @@ -12,7 +12,7 @@ func TestAuthorizedKeys(t *testing.T) { var c integrationtest.Config c.Read() c.Server.Keys = []string{integrationtest.AuthKeyPK} - integrationtest.Backup_then_update_config(c) + integrationtest.Update_config(c) defer integrationtest.Restore_config() integrationtest.Restart_signatory() diff --git a/integration_test/tests/server/jwt_test.go b/integration_test/tests/server/jwt_test.go index 4ea63fb9..05fa5f09 100644 --- a/integration_test/tests/server/jwt_test.go +++ b/integration_test/tests/server/jwt_test.go @@ -72,7 +72,7 @@ func setupJWTConfig(users map[string]*integrationtest.JwtUserData) integrationte // setupAndRestart configures JWT and restarts the signatory service func setupAndRestart(users map[string]*integrationtest.JwtUserData) { config := setupJWTConfig(users) - integrationtest.Backup_then_update_config(config) + integrationtest.Update_config(config) integrationtest.Restart_signatory() } @@ -429,7 +429,7 @@ func TestPerPkh(t *testing.T) { config.Tezos[pkh3].Allow = map[string][]string{"generic": {"transaction"}} config.Tezos[pkh4].Allow = map[string][]string{"generic": {"transaction"}} - integrationtest.Backup_then_update_config(config) + integrationtest.Update_config(config) defer cleanup() integrationtest.Restart_signatory() diff --git a/integration_test/tests/service.go b/integration_test/tests/service.go index ff3a74dd..5363bf10 100644 --- a/integration_test/tests/service.go +++ b/integration_test/tests/service.go @@ -1,4 +1,4 @@ -package new_integration_test +package tests import ( "fmt" @@ -17,7 +17,7 @@ func Restart_signatory() { } } -func Backup_then_update_config(c Config) { +func Update_config(c Config) { err := c.Write() if err != nil { panic("failed to write new config") diff --git a/integration_test/tests/signatorycli.go b/integration_test/tests/signatorycli.go index f2e38ef8..b95754cd 100644 --- a/integration_test/tests/signatorycli.go +++ b/integration_test/tests/signatorycli.go @@ -1,4 +1,4 @@ -package new_integration_test +package tests import ( "os/exec" diff --git a/integration_test/tests/speculos.go b/integration_test/tests/speculos.go index 6c4f06ec..908d35ab 100644 --- a/integration_test/tests/speculos.go +++ b/integration_test/tests/speculos.go @@ -1,4 +1,4 @@ -package new_integration_test +package tests import ( "bytes" diff --git a/integration_test/tests/vaults/vault_aws_test.go b/integration_test/tests/vaults/vault_aws_test.go index 52c8952d..7f0624f6 100644 --- a/integration_test/tests/vaults/vault_aws_test.go +++ b/integration_test/tests/vaults/vault_aws_test.go @@ -35,7 +35,7 @@ func TestAWSVault(t *testing.T) { p.Allow = map[string][]string{"generic": {"reveal", "transaction"}} //c.Tezos[tz2] = &p c.Tezos[tz3] = &p - integrationtest.Backup_then_update_config(c) + integrationtest.Update_config(c) //os.Exit(0) defer integrationtest.Restore_config() integrationtest.Restart_signatory() diff --git a/integration_test/tests/vaults/vault_gcp_test.go b/integration_test/tests/vaults/vault_gcp_test.go index f7b100a7..79128303 100644 --- a/integration_test/tests/vaults/vault_gcp_test.go +++ b/integration_test/tests/vaults/vault_gcp_test.go @@ -29,7 +29,7 @@ func TestGCPVault(t *testing.T) { p.LogPayloads = true p.Allow = map[string][]string{"generic": {"reveal", "transaction"}} c.Tezos[tz3] = &p - integrationtest.Backup_then_update_config(c) + integrationtest.Update_config(c) defer integrationtest.Restore_config() integrationtest.Restart_signatory() diff --git a/integration_test/tests/vaults/vault_hashi_test.go b/integration_test/tests/vaults/vault_hashi_test.go index 251d93a2..d5484038 100644 --- a/integration_test/tests/vaults/vault_hashi_test.go +++ b/integration_test/tests/vaults/vault_hashi_test.go @@ -30,7 +30,7 @@ func TestHashiVault(t *testing.T) { v.Driver = "hashicorpvault" v.Conf = map[string]interface{}{"address": &address, "roleID": &roleid, "secretID": &secretid, "transitConfig": map[string]string{"mountPoint": mountPoint}, "tlsCaCert": "/opt/hashicerts/vault-ca.pem"} c.Vaults["hashicorp"] = &v - integrationtest.Backup_then_update_config(c) + integrationtest.Update_config(c) defer integrationtest.Restore_config() pkh := hashiGetTz1() diff --git a/integration_test/tezos_scripts/init.sh b/integration_test/tezos_scripts/init.sh index d3f967aa..059a969c 100644 --- a/integration_test/tezos_scripts/init.sh +++ b/integration_test/tezos_scripts/init.sh @@ -121,6 +121,11 @@ $client import secret key tz4alias $default_signatory/tz4XXtsYav3fZz2FSDa7hcx4F8 $client --wait none transfer 100000 from bootstrap2 to tz4alias --burn-cap 0.07 $client bake for --minimal-timestamp +# tz4pop +$client import secret key tz4pop $default_signatory/tz4Eb1d5L4njHViVgDDkas7qNgoZgDw6VYPz +$client --wait none transfer 100000 from bootstrap2 to tz4pop --burn-cap 0.07 +$client bake for --minimal-timestamp + # speculos $client import secret key speculos $default_signatory/tz1RVYaHiobUKXMfJ47F7Rjxx5tu3LC35WSA $client --wait none transfer 100000 from bootstrap2 to speculos --burn-cap 0.07 diff --git a/pkg/config/config.go b/pkg/config/config.go index 039de877..8ec48de6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -34,12 +34,13 @@ type TezosConfig = hashmap.PublicKeyHashMap[*TezosPolicy] // TezosPolicy contains policy definition for a specific address type TezosPolicy struct { - Allow map[string][]string `yaml:"allow"` - AllowedOperations []string `yaml:"allowed_operations"` - AllowedKinds []string `yaml:"allowed_kinds"` - LogPayloads bool `yaml:"log_payloads"` - AuthorizedKeys *AuthorizedKeys `yaml:"authorized_keys"` - JwtUsers []string `yaml:"jwt_users"` + Allow map[string][]string `yaml:"allow"` + AllowedOperations []string `yaml:"allowed_operations"` + AllowedKinds []string `yaml:"allowed_kinds"` + AllowProofOfPossession bool `yaml:"allow_proof_of_possession"` + LogPayloads bool `yaml:"log_payloads"` + AuthorizedKeys *AuthorizedKeys `yaml:"authorized_keys"` + JwtUsers []string `yaml:"jwt_users"` } // VaultConfig represents single vault instance diff --git a/pkg/signatory/signatory.go b/pkg/signatory/signatory.go index 967c6db0..b94fe6d9 100644 --- a/pkg/signatory/signatory.go +++ b/pkg/signatory/signatory.go @@ -14,6 +14,7 @@ import ( "strings" "sync" + "github.com/ecadlabs/gotez/v2" "github.com/ecadlabs/gotez/v2/b58" "github.com/ecadlabs/gotez/v2/crypt" "github.com/ecadlabs/gotez/v2/protocol/core" @@ -52,11 +53,12 @@ const ( // PublicKeyPolicy contains policy data related to the key type PublicKeyPolicy struct { - AllowedRequests []string - AllowedOps []string - LogPayloads bool - AuthorizedKeyHashes []crypt.PublicKeyHash - AuthorizedJwtUsers []string + AllowedRequests []string + AllowedOps []string + AllowProofOfPossession bool + LogPayloads bool + AuthorizedKeyHashes []crypt.PublicKeyHash + AuthorizedJwtUsers []string } // PublicKey contains public key with its hash @@ -443,8 +445,14 @@ func (s *Signatory) ProvePossession(ctx context.Context, req *SignRequest) (cryp prover, ok := p.key.(vault.PossessionProver) if !ok { - l.Error("Proof of possession is not supported") - return nil, errors.Wrap(errors.New("proof of possession is not supported"), http.StatusBadRequest) + err = errors.Wrap(errors.New("proof of possession is not supported"), http.StatusBadRequest) + l.Error(err) + return nil, err + } + + if !policy.AllowProofOfPossession { + l.Warn("Proof of possession is not allowed. Proof of possession is required for key reveals, consensus key updates, and companion key registration. To enable, set 'allow_proof_of_possession: true' in the config for this key.") + return nil, errors.Wrap(errors.New("proof of possession is not allowed"), http.StatusBadRequest) } if err = s.callPolicyHook(ctx, req); err != nil { @@ -662,7 +670,8 @@ func PreparePolicy(src config.TezosConfig) (out Policy, err error) { } pol := PublicKeyPolicy{ - LogPayloads: v.LogPayloads, + LogPayloads: v.LogPayloads, + AllowProofOfPossession: false, } if v.Allow != nil { @@ -724,6 +733,14 @@ func PreparePolicy(src config.TezosConfig) (out Policy, err error) { } sort.Strings(pol.AllowedOps) + if v.AllowProofOfPossession { + if _, ok := k.(*gotez.BLSPublicKeyHash); ok { + pol.AllowProofOfPossession = true + } else { + log.Warnf("proof of possession is not supported for %s", k.String()) + } + } + if v.AuthorizedKeys != nil { keys := v.AuthorizedKeys.List() pol.AuthorizedKeyHashes = make([]crypt.PublicKeyHash, len(keys)) diff --git a/pkg/signatory/signatory_test.go b/pkg/signatory/signatory_test.go index 40876ef4..b518bb85 100644 --- a/pkg/signatory/signatory_test.go +++ b/pkg/signatory/signatory_test.go @@ -22,6 +22,7 @@ import ( "github.com/ecadlabs/signatory/pkg/signatory/watermark" "github.com/ecadlabs/signatory/pkg/vault" "github.com/ecadlabs/signatory/pkg/vault/memory" + log "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" yaml "gopkg.in/yaml.v3" ) @@ -435,6 +436,80 @@ func TestPolicy(t *testing.T) { } } +func TestProofOfPossession(t *testing.T) { + type testCase struct { + title string + privKey string + allowPop bool + warning string + expected string + } + + const blsPrivKey = "BLsk2ae63m4ooimmTy1B5wjriwPMtCLdiyNpetFiQMBovRm6ks6rSW" + + var cases = []testCase{ + { + title: "Proof of possession allowed", + privKey: blsPrivKey, + allowPop: true, + }, + { + title: "Proof of possession not allowed", + privKey: blsPrivKey, + allowPop: false, + warning: "level=warning msg=\"Proof of possession is not allowed. Proof of possession is required for key reveals, consensus key updates, and companion key registration. To enable, set 'allow_proof_of_possession: true' in the config for this key.\"", + expected: "proof of possession is not allowed", + }, + { + title: "Proof of possession not supported", + privKey: privateKey, + allowPop: true, + expected: "proof of possession is not supported", + }, + } + + for _, c := range cases { + t.Run(c.title, func(t *testing.T) { + var logs bytes.Buffer + testLogger := log.New() + testLogger.SetOutput(&logs) + + priv, err := crypt.ParsePrivateKey([]byte(c.privKey)) + require.NoError(t, err) + pk := priv.Public() + + conf := signatory.Config{ + Vaults: map[string]*config.VaultConfig{"mock": {Driver: "mock"}}, + Watermark: watermark.Ignore{}, + VaultFactory: vault.FactoryFunc(func(context.Context, string, *yaml.Node, config.GlobalContext) (vault.Vault, error) { + return memory.NewUnparsed([]*memory.UnparsedKey{{Data: priv.String()}}, "Mock"), nil + }), + Policy: hashmap.NewPublicKeyHashMap([]hashmap.PublicKeyKV[*signatory.PublicKeyPolicy]{{Key: pk.Hash(), Val: &signatory.PublicKeyPolicy{ + AllowedRequests: []string{}, + AllowedOps: []string{}, + AllowProofOfPossession: c.allowPop, + LogPayloads: true, + }}}), + Logger: testLogger, + } + + s, err := signatory.New(context.Background(), &conf) + require.NoError(t, err) + require.NoError(t, s.Unlock(context.Background())) + + _, err = s.ProvePossession(context.Background(), &signatory.SignRequest{PublicKeyHash: pk.Hash(), Message: []byte{}}) + if c.warning != "" { + require.Contains(t, logs.String(), c.warning) + } + if c.expected == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, c.expected) + } + }) + } +} + func TestListPublicKeys(t *testing.T) { type testCase struct { title string