-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #201 from alexolivier/envoy-gateway
Add a basic Envoy 'gateway' for locally testing todo app
- Loading branch information
Showing
13 changed files
with
1,110 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Use a specific version of golang for reproducibility | ||
FROM golang:1.23 AS external-pdp | ||
|
||
# Copy go.mod and go.sum files and download dependencies | ||
COPY ./authzen-external-authorizer/go.mod ./authzen-external-authorizer/go.sum ./ | ||
RUN go mod download | ||
|
||
# Copy the source code and build the application | ||
COPY ./authzen-external-authorizer/*.go ./ | ||
RUN CGO_ENABLED=0 GOOS=linux go build -o /external-pdp | ||
|
||
# Use a specific version of envoyproxy for reproducibility | ||
FROM envoyproxy/envoy:v1.31-latest | ||
|
||
# Copy the envoy configuration and entry script | ||
COPY ./envoy/envoy.yaml /tmpl/envoy.yaml.tmpl | ||
COPY ./envoy/envoy-entry.sh / | ||
RUN chmod 500 /envoy-entry.sh | ||
|
||
# Copy the built application from the previous stage | ||
COPY --from=external-pdp /external-pdp /external-pdp | ||
COPY openapi.json openapi.json | ||
RUN chmod 500 /external-pdp | ||
|
||
# Copy the docker entrypoint script and set permissions | ||
COPY docker-entrypoint.sh / | ||
RUN chmod 500 /docker-entrypoint.sh | ||
|
||
# Install gettext for environment variable substitution | ||
RUN apt-get update && apt-get install -y gettext && apt-get clean | ||
|
||
# Set the entrypoint for the container | ||
ENTRYPOINT ["/docker-entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Envoy AuthZEN External Authroizer | ||
|
||
A basic [External Authorization](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter) filter for Envoy. | ||
|
||
``` | ||
docker compose up | ||
``` | ||
|
||
Then the todo application backend will be avaliable on `localhost:9000` with all requests being authorized by the configured PDP. | ||
|
||
Make sure configure the frontend app to use this endpoint rather than `authzen-todo-backend.demo.aserto.com` directly as the Envoy proxy is configured to forward on the request if it is allowed. |
189 changes: 189 additions & 0 deletions
189
interop/authzen-api-gateways/envoy-gateway/authzen-external-authorizer/authzen.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"strings" | ||
"time" | ||
|
||
auth_pb "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" | ||
"github.com/golang-jwt/jwt/v5" | ||
) | ||
|
||
// PDP URLs | ||
var pdps = map[string]string{ | ||
"Aserto": "https://authzen-gateway-proxy.demo.aserto.com", | ||
"Cerbos": "https://authzen-proxy-demo.cerbos.dev", | ||
} | ||
|
||
// AuthZENSubject represents the subject in the authorization request | ||
type AuthZENSubject struct { | ||
Type string `json:"type"` | ||
ID string `json:"id"` | ||
} | ||
|
||
// AuthZENAction represents the action in the authorization request | ||
type AuthZENAction struct { | ||
Name string `json:"name"` | ||
} | ||
|
||
// AuthZENResource represents the resource in the authorization request | ||
type AuthZENResource struct { | ||
Type string `json:"type"` | ||
ID string `json:"id"` | ||
Properties map[string]any `json:"properties"` | ||
} | ||
|
||
// AuthZENRequest represents the authorization request payload | ||
type AuthZENRequest struct { | ||
Subject AuthZENSubject `json:"subject"` | ||
Action AuthZENAction `json:"action"` | ||
Resource AuthZENResource `json:"resource"` | ||
Context map[string]any `json:"context"` | ||
} | ||
|
||
// AuthZENResponse represents the authorization response | ||
type AuthZENResponse struct { | ||
Decision bool `json:"decision"` | ||
} | ||
|
||
// AuthorizeRequest handles the authorization request to the PDP | ||
func (server *AuthServer) AuthorizeRequest(ctx context.Context, request *auth_pb.CheckRequest) (bool, error) { | ||
|
||
// Get PDP URL from request headers | ||
pdpUrl := pdps[request.Attributes.Request.Http.Headers["x_authzen_gateway_pdp"]] | ||
if pdpUrl == "" { | ||
return false, fmt.Errorf("PDP not found: %s", request.Attributes.Request.Http.Headers["x_authzen_gateway_pdp"]) | ||
} | ||
log.Printf("Starting request to PDP: %s\n", pdpUrl) | ||
|
||
// Extract user ID from authorization header | ||
userId, err := extractSubFromBearer(request.Attributes.Request.Http.Headers["authorization"]) | ||
if err != nil { | ||
log.Printf("Failed to extract user ID: %v\n", err) | ||
return false, err | ||
} | ||
|
||
// Construct URL from request attributes | ||
url := fmt.Sprint(request.Attributes.Request.Http.Scheme, "://", request.Attributes.Request.Http.Host, request.Attributes.Request.Http.Path) | ||
|
||
// Match URL to path in OpenAPI spec | ||
route, params, err := MatchURLToPath(server.openApiSpec, url) | ||
if err != nil { | ||
log.Printf("Failed to match URL to path: %v\n", err) | ||
return false, err | ||
} | ||
|
||
log.Printf("Route: %s\n", route) | ||
log.Printf("Params: %v\n", params) | ||
|
||
// Create authorization request payload | ||
authZENPayload := &AuthZENRequest{ | ||
Subject: AuthZENSubject{ | ||
Type: "user", | ||
ID: userId, | ||
}, | ||
Action: AuthZENAction{ | ||
Name: request.Attributes.Request.Http.Method, | ||
}, | ||
Resource: AuthZENResource{ | ||
Type: "route", | ||
ID: route, | ||
Properties: map[string]any{ | ||
"uri": fmt.Sprint(request.Attributes.Request.Http.Scheme, "://", request.Attributes.Request.Http.Host, request.Attributes.Request.Http.Path), | ||
"schema": request.Attributes.Request.Http.Scheme, | ||
"hostname": request.Attributes.Request.Http.Host, | ||
"path": request.Attributes.Request.Http.Path, | ||
"params": params, | ||
"ip": request.Attributes.Request.Http.Headers["x-forwarded-for"], | ||
}, | ||
}, | ||
Context: map[string]any{}, | ||
} | ||
|
||
log.Printf("Sending request to %s", pdpUrl) | ||
|
||
// Encode payload to JSON | ||
payloadBuf := new(bytes.Buffer) | ||
if err := json.NewEncoder(payloadBuf).Encode(authZENPayload); err != nil { | ||
log.Printf("Failed to encode payload: %v\n", err) | ||
return false, err | ||
} | ||
log.Printf("Payload: %+v\n", authZENPayload) | ||
|
||
// Create HTTP request with context | ||
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprint(pdpUrl, "/access/v1/evaluation"), payloadBuf) | ||
if err != nil { | ||
log.Printf("Failed to create request: %v\n", err) | ||
return false, err | ||
} | ||
req.Header.Set("Content-Type", "application/json") | ||
|
||
// Send HTTP request with better error handling | ||
startTime := time.Now() | ||
res, err := server.httpClient.Do(req) | ||
if err != nil { | ||
if ctxErr := ctx.Err(); ctxErr != nil { | ||
log.Printf("Context error during request: %v (request duration: %v)\n", ctxErr, time.Since(startTime)) | ||
return false, fmt.Errorf("context error during request: %v", ctxErr) | ||
} | ||
log.Printf("Failed to send request to PDP: %v (request duration: %v)\n", err, time.Since(startTime)) | ||
return false, fmt.Errorf("failed to send request to PDP: %v", err) | ||
} | ||
requestDuration := time.Since(startTime) | ||
log.Printf("Request duration: %v\n", requestDuration) | ||
|
||
if requestDuration > 5*time.Second { | ||
log.Printf("Warning: Request took longer than 5 seconds") | ||
} | ||
|
||
defer res.Body.Close() | ||
|
||
// Decode response with timeout | ||
var authZENResponse AuthZENResponse | ||
if err := json.NewDecoder(res.Body).Decode(&authZENResponse); err != nil { | ||
log.Printf("Failed to decode response: %v\n", err) | ||
return false, fmt.Errorf("failed to decode response: %v", err) | ||
} | ||
|
||
log.Printf("PDP response received and decoded in %v\n", time.Since(startTime)) | ||
log.Printf("%+v\n", authZENResponse) | ||
|
||
return authZENResponse.Decision, nil | ||
} | ||
|
||
// extractSubFromBearer extracts the subject (sub) claim from the Bearer token | ||
func extractSubFromBearer(authHeader string) (string, error) { | ||
if authHeader == "" { | ||
return "", fmt.Errorf("authorization header missing") | ||
} | ||
|
||
// Check if it's a Bearer token | ||
parts := strings.Split(authHeader, " ") | ||
if len(parts) != 2 || parts[0] != "Bearer" { | ||
return "", fmt.Errorf("invalid authorization header format") | ||
} | ||
|
||
tokenString := parts[1] | ||
|
||
// Parse the JWT token without validation | ||
parser := jwt.NewParser() | ||
token, _, err := parser.ParseUnverified(tokenString, jwt.MapClaims{}) | ||
if err != nil { | ||
return "", fmt.Errorf("failed to parse token: %v", err) | ||
} | ||
|
||
// Extract claims | ||
if claims, ok := token.Claims.(jwt.MapClaims); ok { | ||
if sub, ok := claims["sub"].(string); ok { | ||
return sub, nil | ||
} | ||
return "", fmt.Errorf("subject claim (sub) missing in token") | ||
} | ||
|
||
return "", fmt.Errorf("invalid token claims") | ||
} |
31 changes: 31 additions & 0 deletions
31
interop/authzen-api-gateways/envoy-gateway/authzen-external-authorizer/go.mod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
module github.com/openid/authzen/authzen-todo-envoy-gateway | ||
|
||
go 1.23.5 | ||
|
||
require github.com/envoyproxy/go-control-plane/envoy v1.32.3 | ||
|
||
require ( | ||
github.com/go-openapi/jsonpointer v0.21.0 // indirect | ||
github.com/go-openapi/swag v0.23.0 // indirect | ||
github.com/josharian/intern v1.0.0 // indirect | ||
github.com/mailru/easyjson v0.7.7 // indirect | ||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect | ||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 // indirect | ||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 // indirect | ||
github.com/perimeterx/marshmallow v1.1.5 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) | ||
|
||
require ( | ||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect | ||
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect | ||
github.com/getkin/kin-openapi v0.129.0 | ||
github.com/golang-jwt/jwt/v5 v5.2.1 | ||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect | ||
golang.org/x/net v0.32.0 // indirect | ||
golang.org/x/sys v0.28.0 // indirect | ||
golang.org/x/text v0.21.0 // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect | ||
google.golang.org/grpc v1.70.0 | ||
google.golang.org/protobuf v1.35.2 // indirect | ||
) |
81 changes: 81 additions & 0 deletions
81
interop/authzen-api-gateways/envoy-gateway/authzen-external-authorizer/go.sum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= | ||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/envoyproxy/go-control-plane/envoy v1.32.3 h1:hVEaommgvzTjTd4xCaFd+kEQ2iYBtGxP6luyLrx6uOk= | ||
github.com/envoyproxy/go-control-plane/envoy v1.32.3/go.mod h1:F6hWupPfh75TBXGKA++MCT/CZHFq5r9/uwt/kQYkZfE= | ||
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= | ||
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= | ||
github.com/getkin/kin-openapi v0.129.0 h1:QGYTNcmyP5X0AtFQ2Dkou9DGBJsUETeLH9rFrJXZh30= | ||
github.com/getkin/kin-openapi v0.129.0/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI= | ||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= | ||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= | ||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= | ||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= | ||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= | ||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= | ||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= | ||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= | ||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= | ||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= | ||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= | ||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= | ||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= | ||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= | ||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= | ||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | ||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= | ||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= | ||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= | ||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= | ||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= | ||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= | ||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 h1:nZspmSkneBbtxU9TopEAE0CY+SBJLxO8LPUlw2vG4pU= | ||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80/go.mod h1:7tFDb+Y51LcDpn26GccuUgQXUk6t0CXZsivKjyimYX8= | ||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+7OIuqDwXbhl32HiZGpLy26BAPc= | ||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= | ||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= | ||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= | ||
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/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= | ||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= | ||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= | ||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= | ||
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= | ||
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= | ||
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= | ||
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= | ||
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= | ||
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= | ||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= | ||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= | ||
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= | ||
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= | ||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= | ||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= | ||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= | ||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= | ||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o= | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= | ||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= | ||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= | ||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= | ||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= | ||
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= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
Oops, something went wrong.