Skip to main content
Glama

Trivy

Official
by aquasecurity
verify.go4.18 kB
package creds import ( "bytes" "crypto/hmac" "crypto/sha256" "encoding/base64" "encoding/hex" "encoding/json" "errors" "fmt" "io" "net/http" "strconv" "strings" "time" "github.com/aquasecurity/trivy/pkg/log" "github.com/golang-jwt/jwt/v5" ) type Response struct { Status int `json:"status"` Message string `json:"message"` Data string `json:"data,omitempty"` Errors []string `json:"errors,omitempty"` } type JwtClaims struct { jwt.RegisteredClaims } func (c *AquaCreds) GenerateToken() (string, error) { logger := log.WithPrefix("aqua") logger.Debug("Verifying Aqua credentials") if c.AquaKey == "" || c.AquaSecret == "" || c.Region == "" { return "", fmt.Errorf("aqua credentials are not set") } // Check if the token is still valid if c.Token != "" && c.ExpiresAt > time.Now().Unix() { logger.Debug("Token is still valid") return c.Token, nil } if err := c.Verify(); err != nil { return "", fmt.Errorf("failed to obtain JWT: %w", err) } if err := c.Save(); err != nil { return "", fmt.Errorf("failed to save credentials: %w", err) } return c.Token, nil } func (c *AquaCreds) Verify() error { logger := log.WithPrefix("aqua") logger.Debug("Verifying Aqua credentials") if c.AquaKey == "" || c.AquaSecret == "" { return errors.New("aqua credentials are not set") } response, err := c.obtainJWT() if err != nil { return err } claims, err := decodeJWT(response) if err != nil { return fmt.Errorf("failed to decode JWT: %w", err) } c.Token = response c.ExpiresAt = claims.ExpiresAt.Unix() logger.Debug("Login credentials verified successfully") return nil } func decodeJWT(response string) (*JwtClaims, error) { parts := strings.Split(response, ".") if len(parts) != 3 { return nil, errors.New("invalid JWT token format") } payload, err := base64.RawURLEncoding.DecodeString(parts[1]) if err != nil { return nil, errors.New("failed to decode JWT payload") } var claims JwtClaims err = json.Unmarshal(payload, &claims) if err != nil { return nil, errors.New("failed to unmarshal JWT claims") } return &claims, nil } func (c *AquaCreds) obtainJWT() (string, error) { body := `{"validity":30,"allowed_endpoints":["ANY:v2/build/twirp/buildsecurity.BuildSecurity/*","ANY:v2/log*","ANY:api/*","ANY:v2/build/*"]}` _, cspmUrl := c.GetUrls() // update the URL to use the CSPM endpoint tokenEndpoint := fmt.Sprintf("%s/v2/tokens", cspmUrl) req, err := http.NewRequest("POST", tokenEndpoint, bytes.NewBuffer([]byte(body))) if err != nil { return "", err } timestampString := strconv.Itoa(int(time.Now().Unix())) someString := timestampString + "POST/v2/tokens" + body signature, err := computeHmac256(someString, c.AquaSecret) if err != nil { return "", err } req.Header.Add("x-signature", signature) req.Header.Add("x-timestamp", timestampString) req.Header.Add("x-api-key", c.AquaKey) client := http.Client{ Timeout: 10 * time.Second, } resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("failed sending jwt request token with error: %w", err) } defer func() { _ = resp.Body.Close() }() var response Response debugRawBody := getRawMessageData(resp.Body) resp.Body = io.NopCloser(strings.NewReader(debugRawBody)) err = json.NewDecoder(resp.Body).Decode(&response) if err != nil { return "", fmt.Errorf("failed decoding response with error: %w, raw response body: %s", err, debugRawBody) } if response.Status != 200 { var e = "unknown error" if len(response.Errors) > 0 { e = response.Errors[0] } return "", fmt.Errorf("failed to generate Aqua token with error: %s, %s", response.Message, e) } return response.Data, nil } func computeHmac256(message string, secret string) (string, error) { key := []byte(secret) h := hmac.New(sha256.New, key) _, err := h.Write([]byte(message)) if err != nil { return "", fmt.Errorf("failed writing hmac: %w", err) } return hex.EncodeToString(h.Sum(nil)), nil } func getRawMessageData(rc io.ReadCloser) string { data, err := io.ReadAll(rc) if err != nil { fmt.Println("Error reading RawResponse io.ReadCloser:", err) return "" } return string(data) }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aquasecurity/trivy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server