Help us shape the future of Go! Take the 2026 Go Developer Survey

token

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package token issues and verifies Access tokens (decision 0005): RS256 JWTs signed with a per-instance key, reference tokens and refresh tokens. Only digests of tokens are stored; the store record (token_id, subject, scope, expiry) is what revocation removes.

Index

Constants

View Source
const (
	// DefaultAudience is the audience Access gives a token issued without one.
	DefaultAudience = "*@*"
)
View Source
const (

	// DefaultKeyBits is the RSA key size.
	DefaultKeyBits = 2048
)

Variables

View Source
var (
	// ErrInvalidRequest reports an issue request the service refuses.
	ErrInvalidRequest = errors.New("invalid token request")
	// ErrNeverExpiresAdminOnly refuses a token that never expires to a
	// caller who is not an administrator. It wraps ErrInvalidRequest, which
	// the OIDC exchange answers 400; the token API tests for it first and
	// answers 403, as createtoken documents a refused expires_in.
	ErrNeverExpiresAdminOnly = fmt.Errorf(
		"%w: only an administrator may issue a token that never expires",
		ErrInvalidRequest,
	)
	// ErrNotRevocable refuses to revoke a token shorter than the revocable
	// threshold that was neither forced revocable nor refreshable.
	ErrNotRevocable = errors.New("token is not revocable")
	// ErrRefreshOtherUser refuses a refresh token of another user than the
	// one refreshing: "The authenticated user must match the user of the
	// access token being refreshed" (createtoken.json, which answers 403).
	ErrRefreshOtherUser = errors.New("the refresh token belongs to another user")
)

Functions

This section is empty.

Types

type Issued

type Issued struct {
	Record         types.Token
	AccessToken    string
	RefreshToken   string
	ReferenceToken string
	// ExpiresIn is the lifetime in seconds; zero means never.
	ExpiresIn int64
}

Issued is a new token and its secrets, which are never stored and so cannot be shown again.

type Options

type Options struct {
	// Now supplies the time; nil means time.Now.
	Now func() time.Time
	// KeyBits is the RSA key size; zero means DefaultKeyBits. Only tests set
	// it, to keep key generation cheap.
	KeyBits int
}

Options configures New. Zero values mean the defaults.

type RefreshCheck

type RefreshCheck struct {
	// Username, when set, must be the refreshed token's user, or the refresh
	// fails with ErrRefreshOtherUser.
	Username string
	// TokenID, when set, must be the refreshed token's id, or the refresh
	// fails as an invalid refresh token: the caller presented that token as
	// its credential, and it must not vouch for refreshing another.
	TokenID string
}

RefreshCheck is what a refresh must match beyond a valid refresh token.

type RegistryRequest

type RegistryRequest struct {
	Username string
	// ExpiresIn is the lifetime; it must be positive, and at most
	// types.RegistryTokenExpiry.
	ExpiresIn time.Duration
	Access    types.RegistryAccess
	// Scope is the scope of the credential that obtained the token, which
	// the token keeps so it never acts more broadly; it defaults to
	// applied-permissions/user, a password's.
	Scope types.Scope
	// Identity is that credential's identity when it came from an OIDC
	// exchange, so the token resolves to the same transient or synthetic
	// user it does.
	Identity types.TokenIdentity
	// Parent is the id of the stored token that obtained it, empty for a
	// password or anonymous caller. The token is refused once the parent is
	// revoked.
	Parent string
}

RegistryRequest asks for a registry token (decision 0005).

type Request

type Request struct {
	Username string
	// Scope defaults to applied-permissions/user.
	Scope types.Scope
	// ExpiresIn defaults to token.default_expiry (types.DefaultTokenExpiry
	// when unset); zero means never and needs ByAdmin.
	ExpiresIn      *time.Duration
	Refreshable    bool
	ForceRevocable bool
	Audience       string
	Description    string
	ProjectKey     string
	// IncludeReference also issues a reference token.
	IncludeReference bool
	// ByAdmin is whether the caller is an administrator.
	ByAdmin bool
	// Purpose marks a token its user holds at most one of
	// (types.TokenPurposeEncryptedPassword). Such a token always has a
	// reference token, and keeps it sealed so it can be shown again.
	Purpose string
	// Identity is how the token's subject resolves to a user. An OIDC token
	// exchange, and an administrator minting for a name that is no stored
	// user, issue a token for a user who need not be stored.
	Identity types.TokenIdentity
	// NotAfter, when set, is the latest the token may expire; a longer or
	// unending lifetime is cut to it. A transient user's token for itself
	// sets it to the expiry of the token that minted it: the user exists
	// only through that token, so a token outliving it would outlast the
	// 24 hours an OIDC mapping allows.
	NotAfter time.Time
}

Request asks for a token for a user.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service issues and verifies tokens over a store.

func New

func New(ctx context.Context, st store.Store, o Options) (*Service, error)

New returns a Service. The instance identity must exist: the issuer is jfac@<the instance's id>. The first signing key is created when there is none.

func (*Service) EncryptedPassword

func (s *Service) EncryptedPassword(ctx context.Context, username string) (string, error)

EncryptedPassword returns the user's encrypted password: the reference token of their types.TokenPurposeEncryptedPassword token, which never expires. A user holds at most one, created on first use and shown again after, so every client given it keeps working until the password changes and the identity service revokes it.

func (*Service) Issue

func (s *Service) Issue(ctx context.Context, r Request) (Issued, error)

Issue creates a token.

func (*Service) IssueRegistry

func (s *Service) IssueRegistry(_ context.Context, r RegistryRequest) (Issued, error)

IssueRegistry signs a registry token: an access token with the user's applied permissions whose registry claim carries what it grants. Nothing stores it, as Artifactory stores no token below its persistence threshold, so it cannot be listed or revoked; its short life, the grants and the user's current permissions bound it instead (Verify).

func (*Service) Issuer

func (s *Service) Issuer() string

Issuer is this instance's Access service id, the iss of its tokens.

func (*Service) Refresh

func (s *Service) Refresh(ctx context.Context, refreshToken string) (Issued, error)

Refresh exchanges a refresh token for a new token with the same subject, scope, lifetime and options, and revokes the old one. A refresh token stays usable for types.DefaultRefreshGrace after its token expires.

func (*Service) RefreshAs

func (s *Service) RefreshAs(
	ctx context.Context,
	refreshToken string,
	c RefreshCheck,
) (Issued, error)

RefreshAs is Refresh for a refresh token that must pass c. The user is checked before the token, so another user's refresh token is ErrRefreshOtherUser whichever token the caller presented.

func (*Service) Revoke

func (s *Service) Revoke(ctx context.Context, id string) error

Revoke revokes the token with id.

func (*Service) RevokeValue

func (s *Service) RevokeValue(ctx context.Context, raw string) error

RevokeValue revokes the token whose access or reference token is raw.

func (*Service) Rotate

func (s *Service) Rotate(ctx context.Context) error

Rotate makes a new signing key active. The keys it replaces keep verifying until the latest expiry of the tokens stored now, or for ever when one of them never expires, so no token issued before the rotation is refused early.

func (*Service) Verify

func (s *Service) Verify(ctx context.Context, raw string) (types.Token, error)

Verify resolves an access token (a JWT) or a reference token to its record. A token that is malformed, badly signed, signed by an unknown or retired key, expired, or revoked (no record) fails with an error wrapping auth.ErrInvalidToken.

func (*Service) VerifyExpired

func (s *Service) VerifyExpired(ctx context.Context, raw string) (types.Token, error)

VerifyExpired resolves an access token (a JWT) as Verify does, but accepts one whose only fault is its expiry. Signature, key, revocation and subject are all still checked; a reference token always fails. It serves only the refresh grant, which the JFrog CLI sends with the access token it is replacing, by then often expired. The record outlives its expiry for types.DefaultRefreshGrace (the gc keeps it), which bounds how long after expiry this succeeds.

Jump to

Keyboard shortcuts

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