Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions forge-go/command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
)

var (
serverAppNamespace string
serverDB string
serverRedis string
serverNATS string
Expand Down Expand Up @@ -46,7 +45,6 @@ var (
)

func init() {
ServerCmd.Flags().StringVar(&serverAppNamespace, "app-namespace", "", "Application namespace for keychain and path isolation")
ServerCmd.Flags().StringVar(&serverDB, "db", "", "Database DSN (default: sqlite://<forge-home>/data/forge.db)")
ServerCmd.Flags().StringVar(&serverRedis, "redis", "", "Redis URL (default: embedded miniredis)")
ServerCmd.Flags().StringVar(&serverNATS, "nats", "", "NATS URL for data-plane messaging (e.g. nats://localhost:4222); omit to use Redis")
Expand Down Expand Up @@ -89,10 +87,6 @@ var ServerCmd = &cobra.Command{
l := logging.NewLogger(out, logLevel)
logging.SetGlobalLogger(l)

if serverAppNamespace != "" {
forgepath.SetAppNamespace(serverAppNamespace)
}

db := serverDB
if db == "" {
db = "sqlite://" + forgepath.Resolve("data/forge.db")
Expand Down
34 changes: 12 additions & 22 deletions forge-go/forgepath/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const (
OAuthProvidersConfigFile = "oauth-providers.yaml"
OAuthProvidersConfigEnv = "FORGE_OAUTH_PROVIDERS_CONFIG"
DefaultOAuthProvidersConfigPath = "conf/" + OAuthProvidersConfigFile

KeychainServiceEnv = "FORGE_KEYCHAIN_SERVICE"
DefaultKeychainService = "forge"
)

// DependencyConfigPath returns the dependency config file path, checking the
Expand All @@ -42,33 +45,20 @@ func LocalModelCatalogPath() string {
return DefaultLocalModelCatalogPath
}

func OAuthProvidersConfigPath() string {
if p := os.Getenv(OAuthProvidersConfigEnv); p != "" {
return p
// KeychainService returns the service name used for OS keychain storage.
// Resolution order: FORGE_KEYCHAIN_SERVICE env var → "forge".
func KeychainService() string {
if v := os.Getenv(KeychainServiceEnv); v != "" {
return v
}
return DefaultOAuthProvidersConfigPath
}

var appNamespaceOverride string

// SetAppNamespace sets the application namespace from a CLI flag or runtime
// config. Takes precedence over FORGE_APP_NAMESPACE. Must be called before
// any component reads AppNamespace.
func SetAppNamespace(p string) {
appNamespaceOverride = p
return DefaultKeychainService
}

// AppNamespace returns the application-wide namespace used for keychain
// services, database namespaces, and similar identifiers.
// Resolution order: SetAppNamespace() → FORGE_APP_NAMESPACE → "forge".
func AppNamespace() string {
if appNamespaceOverride != "" {
return appNamespaceOverride
}
if p := os.Getenv("FORGE_APP_NAMESPACE"); p != "" {
func OAuthProvidersConfigPath() string {
if p := os.Getenv(OAuthProvidersConfigEnv); p != "" {
return p
}
return "forge"
return DefaultOAuthProvidersConfigPath
}

var (
Expand Down
206 changes: 103 additions & 103 deletions forge-go/go.mod

Large diffs are not rendered by default.

219 changes: 219 additions & 0 deletions forge-go/go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion forge-go/keychain/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type SecretProvider struct {
}

func NewSecretProvider() *SecretProvider {
return &SecretProvider{service: forgepath.AppNamespace()}
return &SecretProvider{service: forgepath.KeychainService()}
}

func (p *SecretProvider) Resolve(ctx context.Context, key string) (string, error) {
Expand Down
10 changes: 5 additions & 5 deletions forge-go/keychain/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
func TestSecretProvider_PlainSecret(t *testing.T) {
keyring.MockInit()

if err := keyring.Set(forgepath.AppNamespace(), "MY_API_KEY", "sk-abc123"); err != nil {
if err := keyring.Set(forgepath.KeychainService(), "MY_API_KEY", "sk-abc123"); err != nil {
t.Fatalf("seed: %v", err)
}

Expand Down Expand Up @@ -50,7 +50,7 @@ func TestSecretProvider_OAuthToken_NoManager_JSONFallback(t *testing.T) {
keyring.MockInit()

raw := `{"access_token":"ghp_fallback","token_type":"bearer","refresh_token":"","expiry":"0001-01-01T00:00:00Z"}`
if err := keyring.Set(forgepath.AppNamespace(), "oauth:org1|github", raw); err != nil {
if err := keyring.Set(forgepath.KeychainService(), "oauth:org1|github", raw); err != nil {
t.Fatalf("seed: %v", err)
}

Expand All @@ -67,7 +67,7 @@ func TestSecretProvider_OAuthToken_NoManager_JSONFallback(t *testing.T) {
func TestSecretProvider_OAuthToken_NoManager_InvalidJSON(t *testing.T) {
keyring.MockInit()

if err := keyring.Set(forgepath.AppNamespace(), "oauth:org1|github", "not-json"); err != nil {
if err := keyring.Set(forgepath.KeychainService(), "oauth:org1|github", "not-json"); err != nil {
t.Fatalf("seed: %v", err)
}

Expand Down Expand Up @@ -115,7 +115,7 @@ func TestSecretProvider_NonOAuthJSONReturnedRaw(t *testing.T) {
keyring.MockInit()

raw := `{"some_field":"some_value"}`
if err := keyring.Set(forgepath.AppNamespace(), "JSON_SECRET", raw); err != nil {
if err := keyring.Set(forgepath.KeychainService(), "JSON_SECRET", raw); err != nil {
t.Fatalf("seed: %v", err)
}

Expand All @@ -133,7 +133,7 @@ func TestSecretProvider_InDefaultProviderChain(t *testing.T) {
keyring.MockInit()
t.Setenv("FORGE_SECRET_PROVIDERS", "keychain")

if err := keyring.Set(forgepath.AppNamespace(), "CHAIN_KEY", "chain_value"); err != nil {
if err := keyring.Set(forgepath.KeychainService(), "CHAIN_KEY", "chain_value"); err != nil {
t.Fatalf("seed: %v", err)
}

Expand Down
2 changes: 1 addition & 1 deletion forge-go/oauth/keychain_token_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type KeychainTokenStore struct {
}

func NewKeychainTokenStore() *KeychainTokenStore {
return NewKeychainTokenStoreWithService(forgepath.AppNamespace())
return NewKeychainTokenStoreWithService(forgepath.KeychainService())
}

func NewKeychainTokenStoreWithService(service string) *KeychainTokenStore {
Expand Down
2 changes: 1 addition & 1 deletion forge-go/version/version.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package version

var (
Version = "0.4.0"
Version = "0.4.1"
GitCommit = "none"
BuildDate = "unknown"
)
Loading
Loading