MCPcopy Index your code
hub / github.com/coder/coder / IsAuthorized

Method IsAuthorized

coderd/aibridgedserver/aibridgedserver.go:576–643  ·  view source on GitHub ↗

IsAuthorized validates a given Coder API key and returns the user ID to which it belongs (if valid). SECURITY: when in.KeyId is set (the "delegated" path), this method trusts the caller's claim of identity and skips the key-secret check. This is safe only because the DRPCServer is reachable solely

(ctx context.Context, in *proto.IsAuthorizedRequest)

Source from the content-addressed store, hash-verified

574//
575// TODO: replace with logic from [httpmw.ExtractAPIKey].
576func (s *Server) IsAuthorized(ctx context.Context, in *proto.IsAuthorizedRequest) (*proto.IsAuthorizedResponse, error) {
577 //nolint:gocritic // AIBridged has specific authz rules.
578 ctx = dbauthz.AsAIBridged(ctx)
579
580 var (
581 keyID string
582 keySecret string
583 // delegated requests skip the secret check: the caller never
584 // has the secret. Trust is established at the in-process
585 // transport boundary, not in this RPC.
586 delegated bool
587 )
588 switch {
589 case in.GetKey() != "" && in.GetKeyId() != "":
590 return nil, ErrAmbiguousAuth
591 case in.GetKeyId() != "":
592 keyID = in.GetKeyId()
593 delegated = true
594 default:
595 var err error
596 keyID, keySecret, err = httpmw.SplitAPIToken(in.GetKey())
597 if err != nil {
598 return nil, ErrInvalidKey
599 }
600 }
601
602 // Key exists.
603 key, err := s.store.GetAPIKeyByID(ctx, keyID)
604 if err != nil {
605 s.logger.Warn(ctx, "failed to retrieve API key by id", slog.F("key_id", keyID), slog.Error(err))
606 return nil, ErrUnknownKey
607 }
608
609 // Key has not expired.
610 now := dbtime.Now()
611 if key.ExpiresAt.Before(now) {
612 return nil, ErrExpired
613 }
614
615 // Key secret matches (skipped for delegated callers).
616 if !delegated && !apikey.ValidateHash(key.HashedSecret, keySecret) {
617 return nil, ErrInvalidKey
618 }
619
620 // User exists.
621 user, err := s.store.GetUserByID(ctx, key.UserID)
622 if err != nil {
623 s.logger.Warn(ctx, "failed to retrieve API key user", slog.F("key_id", keyID), slog.F("user_id", key.UserID), slog.Error(err))
624 return nil, ErrUnknownUser
625 }
626
627 // User is active, not deleted, and not a system user.
628 if user.Deleted {
629 return nil, ErrDeletedUser
630 }
631 if user.Status != database.UserStatusActive {
632 return nil, ErrInactiveUser
633 }

Callers 2

TestAuthorizationFunction · 0.95

Calls 10

AsAIBridgedFunction · 0.92
SplitAPITokenFunction · 0.92
NowFunction · 0.92
ValidateHashFunction · 0.92
GetKeyIdMethod · 0.80
GetAPIKeyByIDMethod · 0.65
GetUserByIDMethod · 0.65
GetKeyMethod · 0.45
ErrorMethod · 0.45
StringMethod · 0.45

Tested by 2

TestAuthorizationFunction · 0.76