diff --git a/internal/credential/identity_selection.go b/internal/credential/identity_selection.go new file mode 100644 index 000000000..875c775d7 --- /dev/null +++ b/internal/credential/identity_selection.go @@ -0,0 +1,44 @@ +// Copyright (c) 2026 Lark Technologies Pte. Ltd. +// SPDX-License-Identifier: MIT + +package credential + +// CredentialSourceKind is the wire-stable App/credential selection source. +type CredentialSourceKind string + +const ( + SourceFlagProfile CredentialSourceKind = "flag:--profile" + SourceEnvProfile CredentialSourceKind = "env:LARKSUITE_CLI_PROFILE" + SourceEnvAppID CredentialSourceKind = "env:LARKSUITE_CLI_APP_ID" + SourceConfigCurrentApp CredentialSourceKind = "config:currentApp" + SourceConfigFirstApp CredentialSourceKind = "config:firstApp" +) + +// DirectCredentialEnv describes the state of direct app credential env vars. +// It never carries a secret value — only names and the non-sensitive app_id. +type DirectCredentialEnv struct { + Present bool `json:"present"` + Keys []string `json:"keys,omitempty"` + AppID string `json:"appId,omitempty"` + Matched bool `json:"matched,omitempty"` + ConflictsWithProfile bool `json:"conflictsWithProfile,omitempty"` +} + +// IdentitySelection is the explainable result of credential selection. +// It carries NO secret value (security: §5.1). +type IdentitySelection struct { + Source CredentialSourceKind + DirectCredentialEnv DirectCredentialEnv + Suggestion string +} + +// Explicit reports whether the identity was actively specified by the +// user/agent (flag or env), which governs no-fallback behavior. +func (s IdentitySelection) Explicit() bool { + switch s.Source { + case SourceFlagProfile, SourceEnvProfile, SourceEnvAppID: + return true + default: + return false + } +} diff --git a/internal/credential/identity_selection_test.go b/internal/credential/identity_selection_test.go new file mode 100644 index 000000000..326e8753f --- /dev/null +++ b/internal/credential/identity_selection_test.go @@ -0,0 +1,25 @@ +// Copyright (c) 2026 Lark Technologies Pte. Ltd. +// SPDX-License-Identifier: MIT + +package credential + +import "testing" + +func TestIdentitySelectionExplicit(t *testing.T) { + cases := []struct { + src CredentialSourceKind + explicit bool + }{ + {SourceFlagProfile, true}, + {SourceEnvProfile, true}, + {SourceEnvAppID, true}, + {SourceConfigCurrentApp, false}, + {SourceConfigFirstApp, false}, + } + for _, c := range cases { + sel := IdentitySelection{Source: c.src} + if sel.Explicit() != c.explicit { + t.Errorf("source %q: Explicit()=%v want %v", c.src, sel.Explicit(), c.explicit) + } + } +}