1 Commits

Author SHA1 Message Date
Kyle Isom
519f8f8879 sso: add PublicURL for browser authorize (split from backend MciasURL)
Lets services point the browser SSO authorize redirect at the public
MCIAS hostname while keeping the server-to-server code exchange on the
internal/Tailnet address (efficient, edge-independent). PublicURL is
optional and falls back to MciasURL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 11:03:27 -07:00

View File

@@ -39,9 +39,18 @@ const (
// Config holds the SSO client configuration. The values must match the
// SSO client registration in MCIAS config.
type Config struct {
// MciasURL is the base URL of the MCIAS server.
// MciasURL is the base URL of the MCIAS server used for the
// server-to-server authorization-code exchange. This is typically the
// internal/Tailnet address so the exchange does not depend on the public
// edge.
MciasURL string
// PublicURL, when set, is the browser-facing MCIAS base URL used to build
// the authorize redirect. It must be resolvable and reachable by end-user
// browsers (e.g. the public hostname). When empty, MciasURL is used for
// both, which only works when MciasURL is itself browser-reachable.
PublicURL string
// ClientID is the registered SSO client identifier.
ClientID string
@@ -104,9 +113,19 @@ func New(cfg Config) (*Client, error) {
}, nil
}
// AuthorizeURL returns the MCIAS authorize URL with the given state parameter.
// authorizeBase returns the browser-facing MCIAS base URL: PublicURL when
// configured, otherwise MciasURL.
func (c *Client) authorizeBase() string {
if c.cfg.PublicURL != "" {
return c.cfg.PublicURL
}
return c.cfg.MciasURL
}
// AuthorizeURL returns the MCIAS authorize URL (browser-facing) with the
// given state parameter.
func (c *Client) AuthorizeURL(state string) string {
base := strings.TrimRight(c.cfg.MciasURL, "/")
base := strings.TrimRight(c.authorizeBase(), "/")
return base + "/sso/authorize?" + url.Values{
"client_id": {c.cfg.ClientID},
"redirect_uri": {c.cfg.RedirectURI},