func()

in assertion/pkg/tasks/assertion/verify.go [41:112]


func (t *Verify) Run(ctx context.Context) error {
	// Check arguments
	if t.JWKS == nil {
		return fmt.Errorf("JWKS must not be nil")
	}

	// Retrieve content reader
	reader, err := t.ContentReader(ctx)
	if err != nil {
		return fmt.Errorf("unable to open content for read: %w", err)
	}

	// Drain input
	assertion, err := io.ReadAll(reader)
	if err != nil {
		return fmt.Errorf("unable to read assertion from reader: %w", err)
	}
	if len(assertion) == 0 {
		return fmt.Errorf("assertion is empty")
	}

	// Parse assertion
	token, err := jwt.ParseSigned(string(assertion))
	if err != nil {
		return fmt.Errorf("invalid assertion, syntax error: %w", err)
	}

	// Check headers
	if errValidationHeaders := t.validateHeaders(token); errValidationHeaders != nil {
		return errValidationHeaders
	}

	// Iterate over JWKS
	var (
		body   map[string]interface{}
		claims jwt.Claims
	)

	valid := false
	for idx := range t.JWKS.Keys {
		// Use index for lower memory usage
		jwk := t.JWKS.Keys[idx]

		// Check signature
		if err = token.Claims(jwk, &body, &claims); err == nil {
			valid = true
			break
		}
	}
	if !valid {
		return fmt.Errorf("unable to valid assertion signature")
	}

	// Validate claims
	if errValidationClaims := t.validateClaims(&claims); errValidationClaims != nil {
		return errValidationClaims
	}

	// Allocate writer
	writer, err := t.OutputWriter(ctx)
	if err != nil {
		return fmt.Errorf("unable to allocate output writer: %w", err)
	}

	// Write payload
	if err = json.NewEncoder(writer).Encode(body); err != nil {
		return fmt.Errorf("unable to encode content as JSON: %w", err)
	}

	// No error
	return nil
}