mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
The verifier built only from an OAuth2 login-source row, so every credential this instance can verify depended on the prerequisites of browser sign-in. With no source configured -- which is the state a deployment is in until its client secret is seeded -- a git push, a CI clone and a package pull were all unverifiable, though not one of them presents anything but a bearer. Verifying needs the issuer's public keys and nothing else: no client credential, no row. The [iam] block the deployment already writes says which issuer, and until now nothing in Go read it. A registered source still wins where there is one, so an instance that has completed the browser setup is unchanged.
41 lines
1.7 KiB
Go
41 lines
1.7 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package setting
|
|
|
|
import "github.com/hanzoai/git/modules/log"
|
|
|
|
// IAM is the identity provider this instance verifies credentials against.
|
|
//
|
|
// The deployment already writes this block — `[iam] ISSUER / AUDIENCE /
|
|
// LOGIN_SOURCE` is in the shipped app.ini — and until now nothing in Go read it.
|
|
// It was inert configuration describing the one thing the instance most needed to
|
|
// know, which is why the verifier had no source but the database.
|
|
//
|
|
// It exists to DECOUPLE two questions that are not the same:
|
|
//
|
|
// - "can I verify a bearer this issuer signed" — needs the issuer's public keys
|
|
// and nothing else, so it needs no secret and no row;
|
|
// - "can a browser sign in here" — needs a registered OAuth2 login source,
|
|
// because the authorization-code exchange authenticates the client.
|
|
//
|
|
// Coupling them cost the second's prerequisites to the first: with no login
|
|
// source configured, a git push, a CI clone and a package pull — every one of
|
|
// which presents a bearer and needs no client credential at all — could not be
|
|
// verified either.
|
|
var IAM = struct {
|
|
// Issuer is the OIDC issuer, e.g. https://hanzo.id. Discovery is derived from
|
|
// it, so a deployment states one URL rather than two that can disagree.
|
|
Issuer string `ini:"ISSUER"`
|
|
// Audience is this instance's own client id, e.g. hanzo-git. Recorded for
|
|
// operators and for a future audience check; the issuer allowlist is what
|
|
// fails closed today (see services/auth/iam.go).
|
|
Audience string `ini:"AUDIENCE"`
|
|
}{}
|
|
|
|
func loadIAMFrom(rootCfg ConfigProvider) {
|
|
if err := rootCfg.Section("iam").MapTo(&IAM); err != nil {
|
|
log.Fatal("Failed to map IAM settings: %v", err)
|
|
}
|
|
}
|