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