[go: up one dir, main page]

Skip to content

Create internal API endpoint for SDRS callbacks

Description

Implement a secure internal API endpoint to receive verification results from SDRS using JWT authentication.

Acceptance Criteria

  • Create API::Internal::TokenStatus endpoint
  • Implement JWT validation for incoming requests
  • Validate JWT claims (exp, iss, aud, etc.)
  • Update FindingTokenStatus with received status
  • Handle all possible status values (active, revoked, error)
  • Implement request correlation using jti claim
  • Add rate limiting
  • Log all callback attempts for audit
  • Return appropriate HTTP status codes

Implementation Plan

module API
  module Internal
    class TokenStatus < ::API::Base
      before { authenticate_sdrs_callback! }
      
      namespace 'internal' do
        desc 'Receive token status callback from SDRS'
        params do
          requires :finding_id, type: Integer
          requires :status, type: String, values: %w[active revoked error]
          optional :metadata, type: Hash
          requires :checked_at, type: DateTime
        end
        post 'token_status/callback' do
          finding = Vulnerabilities::Finding.find(params[:finding_id])
          
          # Verify the finding matches JWT claims
          jwt_claims = env['sdrs.jwt_claims']
          forbidden! unless jwt_claims['gitlab']['finding_id'] == params[:finding_id]
          
          # Update status
          token_status = finding.secret_detection_token_statuses.find_or_initialize_by(
            token_field: finding.token_field
          )
          
          token_status.update!(
            status: params[:status],
            metadata: params[:metadata],
            checked_at: params[:checked_at]
          )
          
          # Log for audit
          Gitlab::AppLogger.info(
            message: 'SDRS callback received',
            finding_id: params[:finding_id],
            status: params[:status],
            jti: jwt_claims['jti']
          )
          
          status 200
        end
      end
      
      private
      
      def authenticate_sdrs_callback!
        token = request.headers['Authorization']&.split(' ')&.last
        unauthorized! unless token
        
        begin
          payload = JWT.decode(
            token,
            sdrs_public_key,
            true,
            { 
              algorithm: 'RS256',
              verify_iss: true,
              iss: 'secret-detection-response-service',
              verify_aud: true,
              aud: 'gitlab-secret-detection-callback',
              verify_iat: true
            }
          )
          
          env['sdrs.jwt_claims'] = payload.first
        rescue JWT::DecodeError => e
          unauthorized!
        end
      end
    end
  end
end
Edited by Aditya Tiwari