in internal/sshd/server_config.go [166:211]
func (s *serverConfig) handleUserCertificate(ctx context.Context, user string, cert *ssh.Certificate) (*ssh.Permissions, error) {
if os.Getenv("FF_GITLAB_SHELL_SSH_CERTIFICATES") != "1" {
return nil, fmt.Errorf("handleUserCertificate: feature is disabled")
}
fingerprint := ssh.FingerprintSHA256(cert.SignatureKey)
if cert.CertType != ssh.UserCert {
return nil, fmt.Errorf("handleUserCertificate: cert has type %d", cert.CertType)
}
certChecker := &ssh.CertChecker{}
if err := certChecker.CheckCert(user, cert); err != nil {
return nil, err
}
logger := log.WithContextFields(ctx,
log.Fields{
"ssh_user": user,
"public_key_fingerprint": ssh.FingerprintSHA256(cert),
"signing_ca_fingerprint": fingerprint,
"certificate_identity": cert.KeyId,
},
)
res, err := s.authorizedCertsClient.GetByKey(ctx, cert.KeyId, strings.TrimPrefix(fingerprint, "SHA256:"))
if err != nil {
logger.WithError(err).Warn("user certificate is not signed by a trusted key")
return nil, err
}
logger.WithFields(
log.Fields{
"certificate_username": res.Username,
"certificate_namespace": res.Namespace,
},
).Info("user certificate is signed by a trusted key")
return &ssh.Permissions{
Extensions: map[string]string{
"username": res.Username,
"namespace": res.Namespace,
},
}, nil
}