func()

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
}