auth

package
v0.27.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const RouterAppURL = "https://app.nullify.ai"

RouterAppURL is the dashboard URL for users who sign in through the router.

View Source
const RouterHost = "nullify.ai"

RouterHost is the bare host of the Nullify router, which serves sign-in but not tenant data.

Variables

View Source
var ErrNoDataHost = errors.New("no organization selected for the router sign-in - run 'nullify auth login'")

ErrNoDataHost reports that the router credentials have no selected installation.

View Source
var ErrNoOrgs = errors.New("no organization on this host is available to you")

ErrNoOrgs reports that the user has no org routed to this host.

View Source
var ErrNotRefreshable = errors.New("no refresh token stored")

ErrNotRefreshable reports that the stored credentials for a host carry no refresh token, so no amount of retrying will produce a new access token.

View Source
var ErrOrgNotFound = errors.New("organization not available")

ErrOrgNotFound reports that an org named by the user is not one of theirs on this host.

View Source
var ErrTokenRejected = errors.New("token rejected")

ErrTokenRejected reports that the org list refused the token, which can happen before its stored expiry (revocation, clock skew).

Functions

func AuthHostFor added in v0.27.0

func AuthHostFor(host string) (string, error)

AuthHostFor returns the host whose credentials serve host: the auth host recorded at login, or host itself for a login made before the CLI asked (those credentials are stored under the tenant's own key).

func BindTenant added in v0.27.0

func BindTenant(tenant string, router Router) error

BindTenant records that tenant signs in through router, unless it already does.

func CheckSession added in v0.26.0

func CheckSession(ctx context.Context, host string) error

CheckSession returns an error unless host has a valid token and, for the router, a selected installation.

func CoverSelectedTenant added in v0.27.0

func CoverSelectedTenant(tenant string) (bool, error)

CoverSelectedTenant binds tenant to the router login whose selected data host it is, as a CLI v0.26.0 login leaves it, without asking the router.

func CoverTenant added in v0.27.0

func CoverTenant(ctx context.Context, tenant string) (bool, error)

CoverTenant binds tenant to a stored router login that lists one of the user's orgs on it, and reports whether one did: a router login covers every tenant it lists, including one added after the login.

func CredentialKey added in v0.13.0

func CredentialKey(host string) string

CredentialKey normalizes a host to its bare form (without "api." prefix) so that credentials are stored and looked up consistently regardless of whether the caller passes "acme.nullify.ai" or "api.acme.nullify.ai".

func DataHost added in v0.26.0

func DataHost(authHost string) (string, error)

DataHost returns the host that serves data for the credentials stored under authHost.

func DeleteHostCredentials

func DeleteHostCredentials(host string) error

func DiscoverAuthHost added in v0.27.0

func DiscoverAuthHost(ctx context.Context, host string) (string, error)

DiscoverAuthHost asks host where its CLI login runs (GET /auth/cli/config). A stack that predates the endpoint answers 404 and logs in on its own host. Any other failure, or an answer that is neither this tenant nor a known router, is an error: credentials never go to a host the CLI did not expect, and a failed discovery is never retried on another host.

func ForceRefreshToken added in v0.25.3

func ForceRefreshToken(ctx context.Context, host string) (string, error)

ForceRefreshToken exchanges the stored refresh token for a new access token regardless of the recorded expiry. GetValidToken only refreshes once ExpiresAt has elapsed, which leaves callers no way to recover from a token the server rejects while the CLI still believes it is valid -- revocation, a killed session, or a local clock running behind the server's.

func GetValidToken

func GetValidToken(ctx context.Context, host string) (string, error)

func IsRouterHost added in v0.26.0

func IsRouterHost(host string) bool

IsRouterHost reports whether host is a bare, "api." or "app." form of a router host.

func KnownHosts added in v0.27.0

func KnownHosts() ([]string, error)

KnownHosts lists the API hosts the user is signed in to, sorted. Router credentials are shared by the tenants bound to them, so the router's own key is listed only when no tenant is.

func Login

func Login(ctx context.Context, host string, picker InstallationPicker) error

Login signs in for host in the browser. A router host signs in at that router. A tenant host is asked where its CLI login runs: a tenant on a router signs in at the router, which then covers every tenant it lists for the user, and picker chooses the org among those on host; any other tenant signs in itself.

func Logout

func Logout(host string) error

Logout removes the credentials that serve host. On a router tenant those are the router login, shared with every other tenant signed in through it.

func OpenBrowser added in v0.13.0

func OpenBrowser(url string) error

OpenBrowser opens the given URL in the user's default browser.

func RememberOrg added in v0.27.0

func RememberOrg(org Org) error

RememberOrg makes org the default for its data host without moving the default host: a router login's selection follows only when it is already on that data host.

func SaveConfig

func SaveConfig(cfg *Config) error

func SaveCredentials

func SaveCredentials(creds Credentials) error

func SaveHostCredentials

func SaveHostCredentials(host string, hostCreds HostCredentials) error

func SelectOrg added in v0.27.0

func SelectOrg(org Org) error

SelectOrg makes org the default for its data host and, for a router login, moves the router's selected data host to it and makes the router the default host. The login picker, 'nullify org use' and 'nullify auth switch --installation' save through here; the prompt uses RememberOrg, which does not move the default host.

func UpdateHostConfig added in v0.27.0

func UpdateHostConfig(host string, update func(HostConfig) HostConfig) error

UpdateHostConfig applies update to the stored config for host and saves it.

Types

type Config

type Config struct {
	Host string `json:"host"`
}

func LoadConfig

func LoadConfig() (*Config, error)

type Credentials

type Credentials map[string]HostCredentials

func LoadCredentials

func LoadCredentials() (Credentials, error)

type ErrOrgNotChosen added in v0.27.0

type ErrOrgNotChosen struct {
	Host string
	Orgs []Org
	// Unavailable is the remembered org when it is no longer one of Orgs.
	Unavailable *OrgPick
}

ErrOrgNotChosen reports that several orgs could serve the request and nothing chose one. Orgs lists the choices.

func (*ErrOrgNotChosen) Error added in v0.27.0

func (e *ErrOrgNotChosen) Error() string

type HostConfig added in v0.27.0

type HostConfig struct {
	AuthHost string   `json:"auth_host,omitempty"`
	Org      *OrgPick `json:"org,omitempty"`
}

HostConfig is what the CLI remembers about one API host. AuthHost is the host that ran its login and serves its refresh, which on a router tenant is the router rather than the tenant itself. Org is the org the user picked for this host, if any.

type HostCredentials

type HostCredentials struct {
	AccessToken     string            `json:"access_token"`
	RefreshToken    string            `json:"refresh_token"`
	ExpiresAt       int64             `json:"expires_at"`
	QueryParameters map[string]string `json:"query_parameters,omitempty"`
	DataHost        string            `json:"data_host,omitempty"`
	Installation    string            `json:"installation,omitempty"`
}

func LookupCredentials added in v0.27.0

func LookupCredentials(host string) (hostCreds HostCredentials, authHost string, ok bool, err error)

LookupCredentials returns the stored credentials that serve host and the auth host they belong to. ok is false when none are stored.

type Hosts added in v0.27.0

type Hosts map[string]HostConfig

Hosts maps an API host, in CredentialKey form, to its HostConfig. It lives apart from credentials.json because it holds no secrets, and apart from config.json because callers rewrite that file whole.

func LoadHosts added in v0.27.0

func LoadHosts() (Hosts, error)

LoadHosts returns the stored host bindings, empty when none were saved.

type InstallationPicker added in v0.26.0

type InstallationPicker struct {
	Name        string
	Interactive bool
	In          io.Reader
	Out         io.Writer
	// Remembered is the org last chosen, used when it is still offered.
	Remembered *OrgPick
}

InstallationPicker selects the org a router login starts with: by name or id, the one remembered for its host, by prompt, or the only one.

func (InstallationPicker) Pick added in v0.26.0

func (p InstallationPicker) Pick(orgs []Org) (Org, error)

Pick returns the selected org from orgs.

type Org added in v0.27.0

type Org struct {
	Name     string `json:"name"`
	Provider string `json:"provider"`
	Key      string `json:"key"`
	ID       string `json:"id"`
	// Host is the API host serving the org, empty when the router has not
	// routed it yet.
	Host string `json:"host,omitempty"`
	// Status is the router's provisioning status: ready, pending or
	// unavailable. Empty outside router mode.
	Status string `json:"status,omitempty"`
}

Org is one organization a request can be scoped to on an API host. Key and ID are the query parameter that scopes a request to it, e.g. githubOwnerId=1001001.

func ResolveOrg added in v0.27.0

func ResolveOrg(host string, list OrgList, in OrgInputs) (Org, error)

ResolveOrg picks the org a request on host runs as; see ResolveOrgReason.

func ResolveOrgReason added in v0.27.0

func ResolveOrgReason(host string, list OrgList, in OrgInputs) (Org, string, error)

ResolveOrgReason picks the org a request on host runs as, from list and in, and says which rule picked it: an explicit name or id (--org, then NULLIFY_ORG, then NULLIFY_GITHUB_OWNER_ID), the git remote owner if it names exactly one org, the remembered pick, the only org. An explicit name that matches nothing is an error, never a fallthrough, and so is a remembered pick that is no longer available: another org is never put in its place. Anything left ambiguous returns *ErrOrgNotChosen; the lowest id is never a default.

func SwitchInstallation added in v0.26.0

func SwitchInstallation(ctx context.Context, router Router, name string) (Org, error)

SwitchInstallation selects the named org among the router login's and makes the router the default host.

func (Org) DataHost added in v0.27.0

func (o Org) DataHost() string

DataHost is the org's API host in credential key form, "" when unrouted.

func (Org) Matches added in v0.27.0

func (o Org) Matches(ref string) bool

Matches reports whether ref names the org, by name (case-insensitive) or id.

func (Org) Query added in v0.27.0

func (o Org) Query() map[string]string

Query returns the query parameters that scope a request to the org.

func (Org) String added in v0.27.0

func (o Org) String() string

type OrgInputs added in v0.27.0

type OrgInputs struct {
	// Flag is --org, or a caller's equivalent (an MCP tool's org argument).
	Flag string
	// FlagSource names Flag in errors, e.g. "--org".
	FlagSource string
	// EnvOrg is NULLIFY_ORG.
	EnvOrg string
	// EnvGitHubOwnerID is NULLIFY_GITHUB_OWNER_ID.
	EnvGitHubOwnerID string
	// Stored is the remembered pick for this host.
	Stored *OrgPick
	// GitOwner is the owner in the current directory's git remote.
	GitOwner string
	// AnyHost lets an explicit name or id match an org on another host of
	// the same router, for a command that moves to that org's host.
	AnyHost bool
}

OrgInputs are the ways a command can name its org, in precedence order.

type OrgList added in v0.27.0

type OrgList struct {
	// Orgs are served by this host and can scope its requests.
	Orgs []Org
	// Pending are the user's orgs the router has not finished routing.
	Pending []Org
	// Elsewhere are the user's orgs served by another Nullify host.
	Elsewhere []Org
}

OrgList is what the signed-in user can see from one API host.

func ListOrgs added in v0.27.0

func ListOrgs(ctx context.Context, host, listHost, token string) (OrgList, error)

ListOrgs returns the orgs token can scope requests to on host, read from GET /admin/installations on listHost: the router for a router login, the tenant itself for a legacy login or an API token. An org counts for host when its nullifyBaseUrl names host; when listHost is host itself, an installation with no base URL is the tenant's own.

type OrgPick added in v0.27.0

type OrgPick struct {
	Name string `json:"name"`
	Key  string `json:"key"`
	ID   string `json:"id"`
}

OrgPick is an org the user chose explicitly for a host, with `nullify org use` or at the prompt. It is the only scope the CLI remembers.

func StoredPick added in v0.27.0

func StoredPick(dataHost string) *OrgPick

StoredPick returns the org remembered for dataHost: the one saved by a login or 'nullify org use', else the installation a CLI v0.26.0 router login selected there, which this version takes over as the same choice. It is returned even when the org is no longer available, so the caller can say so instead of quietly using another.

type Router added in v0.27.0

type Router struct {
	Key      string
	AuthHost string
	AppURL   string
	// contains filtered or unexported fields
}

Router is one Nullify router environment. Key is where its login is stored and the host commands name it by; AuthHost serves sign-in and the org list; a data host it lists must be api.<label>.<dataDomain>, and any other is never contacted.

func RouterFor added in v0.27.0

func RouterFor(host string) (Router, bool)

RouterFor returns the router environment host names in its bare, "api." or "app." form.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL