mirror of
https://github.com/hanzoai/kms.git
synced 2026-10-17 11:18:16 +00:00
* docs(llm): explicit Upstream attribution line
LICENSE-attested or repo-attested upstream is now called out at the
top of LLM.md alongside the project description, so downstream
audits (universe/docs/PRODUCTS.md) can rely on a single canonical
location for the OSS lineage statement.
* feat: cloud Mount() per HIP-0106
Adds pkg/kms.Mount(*zip.App, cloud.Deps) error so the unified Hanzo
Cloud binary can blank-import and register the in-process KMS
server alongside every other Hanzo subsystem.
- pkg/kms/mount.go: native /v1/kms/health + /v1/kms/readyz zip
handlers and zip.AdaptNetHTTP wrap of the existing Embed mux at
/v1/kms/* + /healthz. init() registers with cloud.Register("kms",
10, …) so blank import wires the subsystem in.
- cmd/kmsd: rewritten as a HIP-0106 thin shim — cloud.LoadConfig +
cloud.BuildDeps + zip.New + kms.Mount + app.Listen. The Embed
surface is unchanged; only assembly moves through zip.
- schema/kms.zap: minimal Health ZAP interface; full secret/key
surfaces land in follow-up PRs.
Standalone kmsd binary still ships via the existing Dockerfile and
CI workflow.
* refactor: collapse pkg/kms/ → root for clean import path
Subsystem code lives in package kms at repo root. Importers now use
`github.com/hanzoai/kms` (no /pkg/kms/ nesting). Standalone shim moved
to cmd/kms/ where applicable.
Per Hanzo Go-stdlib pattern: repo IS the package.
* refactor: flatten import path — github.com/hanzoai/cloud (drop /pkg/cloud)
92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
// Shared test utilities. The package-level sharedTestJWT is bound during
|
|
// TestMain so every test can produce a signed JWT without re-spinning a
|
|
// JWKS server per test.
|
|
//
|
|
// This replaces the previous mintToken() unsigned-JWT helper. Post-patch
|
|
// the KMS authz layer requires real RS256 signatures; an unsigned token
|
|
// returns 401 (as Red F3 demands).
|
|
package kms
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"math/big"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
// shared fixtures bound in TestMain.
|
|
var (
|
|
sharedPriv *rsa.PrivateKey
|
|
sharedKid = "kms-shared-test-kid"
|
|
sharedJWKS *httptest.Server
|
|
sharedIssuer = "https://iam.test.hanzo.id"
|
|
sharedAudience = "kms"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
// Generate a single RSA key for the whole test binary.
|
|
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
panic("testutil: keygen: " + err.Error())
|
|
}
|
|
sharedPriv = priv
|
|
|
|
nB64 := base64.RawURLEncoding.EncodeToString(priv.N.Bytes())
|
|
eB64 := base64.RawURLEncoding.EncodeToString(big.NewInt(int64(priv.E)).Bytes())
|
|
jwksJSON, _ := json.Marshal(map[string]any{
|
|
"keys": []map[string]string{
|
|
{"kty": "RSA", "kid": sharedKid, "use": "sig", "alg": "RS256", "n": nB64, "e": eB64},
|
|
},
|
|
})
|
|
sharedJWKS = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write(jwksJSON)
|
|
}))
|
|
|
|
os.Setenv("IAM_ISSUER", sharedIssuer)
|
|
os.Setenv("IAM_AUDIENCE", sharedAudience)
|
|
os.Setenv("IAM_KEYS_URL", sharedJWKS.URL)
|
|
os.Setenv("KMS_ENV", "dev")
|
|
|
|
applyAuthConfig(loadAuthConfig())
|
|
resetJWKSCacheForTest()
|
|
|
|
code := m.Run()
|
|
sharedJWKS.Close()
|
|
os.Exit(code)
|
|
}
|
|
|
|
// mintTestJWTSigned produces an RS256-signed JWT using the shared test
|
|
// keypair + kid + JWKS. Defaults iss/aud/exp/iat to the shared test
|
|
// fixtures unless the caller overrides them.
|
|
func mintTestJWTSigned(t *testing.T, claims jwt.MapClaims) string {
|
|
t.Helper()
|
|
if _, ok := claims["iss"]; !ok {
|
|
claims["iss"] = sharedIssuer
|
|
}
|
|
if _, ok := claims["aud"]; !ok {
|
|
claims["aud"] = sharedAudience
|
|
}
|
|
if _, ok := claims["exp"]; !ok {
|
|
claims["exp"] = time.Now().Add(10 * time.Minute).Unix()
|
|
}
|
|
if _, ok := claims["iat"]; !ok {
|
|
claims["iat"] = time.Now().Unix()
|
|
}
|
|
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
|
token.Header["kid"] = sharedKid
|
|
s, err := token.SignedString(sharedPriv)
|
|
if err != nil {
|
|
t.Fatalf("mintTestJWTSigned: %v", err)
|
|
}
|
|
return s
|
|
}
|