omni/internal/backend/oidc/oidc.go
Artem Chernyshev ed946b30a6
feat: display OMNI_ENDPOINT in the service account creation UI
Fixes: https://github.com/siderolabs/omni/issues/858

Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
2025-01-29 15:27:36 +03:00

96 lines
2.4 KiB
Go

// Copyright (c) 2025 Sidero Labs, Inc.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
// Package oidc implements OIDC server.
package oidc
import (
"context"
"crypto/rand"
"fmt"
"github.com/cosi-project/runtime/pkg/state"
"github.com/sirupsen/logrus"
oidc_logging "github.com/zitadel/logging"
"github.com/zitadel/oidc/v3/pkg/op"
"go.uber.org/zap"
"github.com/siderolabs/omni/client/pkg/constants"
"github.com/siderolabs/omni/internal/backend/oidc/internal/storage"
"github.com/siderolabs/omni/internal/pkg/config"
)
func init() {
oidc_logging.SetFormatter(&logrus.JSONFormatter{})
}
// NewStorage creates OIDC internal storage.
func NewStorage(st state.State, logger *zap.Logger) Storage {
return storage.NewStorage(st, logger)
}
// Provider combines OIDC provider and storage.
type Provider struct {
op.OpenIDProvider
storage Storage
}
// NewProvider creates new OIDC provider.
func NewProvider(store Storage) (*Provider, error) {
issuerEndpoint, err := config.Config.GetOIDCIssuerEndpoint()
if err != nil {
return nil, err
}
// generate fresh crypto key time, as all auth requests are ephemeral in the storage
var cryptoKey [32]byte
_, err = rand.Read(cryptoKey[:])
if err != nil {
return nil, fmt.Errorf("failed to generate crypto key: %w", err)
}
cfg := &op.Config{
CryptoKey: cryptoKey,
DefaultLogoutRedirectURI: "/logout",
CodeMethodS256: true,
AuthMethodPost: true,
AuthMethodPrivateKeyJWT: true,
GrantTypeRefreshToken: false,
RequestObjectSupported: true,
}
var opts []op.Option
if constants.IsDebugBuild {
// allow HTTP in OIDC issuer endpoint
opts = append(opts, op.WithAllowInsecure())
}
h, err := op.NewProvider(cfg, store, op.StaticIssuer(issuerEndpoint), opts...)
if err != nil {
return nil, err
}
return &Provider{
OpenIDProvider: h,
storage: store,
}, nil
}
// AuthenticateRequest authenticates OIDC request.
func (p *Provider) AuthenticateRequest(requestID, identity string) error {
return p.storage.AuthenticateRequest(requestID, identity)
}
// Storage is the OIDC storage interface. It's here because storage.Storage is in internal package.
type Storage interface {
op.Storage
AuthenticateRequest(requestID, identity string) error
GetPublicKeyByID(keyID string) (any, error)
Run(context.Context) error
}