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

apiaccess

package
v0.0.12 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2026 License: Apache-2.0, MIT Imports: 22 Imported by: 0

Documentation

Overview

Package apiaccess manages machine authorization: API definitions with scopes and client grants. The federation module evaluates machine-token access via a consumer-side adapter, so this package never imports it.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound       = errors.New("apiaccess: api not found")
	ErrDuplicate      = errors.New("apiaccess: api resource already exists")
	ErrUnknownClient  = errors.New("apiaccess: unknown oidc client")
	ErrUnknownPerms   = errors.New("apiaccess: unknown permission ids")
	ErrInvalidSubject = errors.New("apiaccess: invalid grant subject")
)

Errors surfaced by the store; statuses live on the sentinels.

Functions

This section is empty.

Types

type API

type API struct {
	ID               APIID        `json:"id"`
	Name             string       `json:"name"`
	Resource         string       `json:"resource"`
	AllowCIMDClients bool         `json:"allow_cimd_clients"`
	Permissions      []Permission `json:"permissions"`
	CreatedAt        time.Time    `json:"created_at"`
	UpdatedAt        *time.Time   `json:"updated_at,omitzero"`
}

API is one resource server definition.

type APIID

type APIID = typeid.TypeID[apiPrefix]

Typed IDs: only URL-facing IDs carry a TypeID; permission IDs are UUIDs are exposed as opaque strings.

type ClientRef

type ClientRef struct {
	ID         string `json:"id"`
	Name       string `json:"name"`
	ClientType string `json:"client_type"`
	IsPublic   bool   `json:"is_public"`
}

ClientRef is the apiClientDto shape: the OIDC client subset the API admin UI renders.

type CreateParams

type CreateParams struct {
	Name     string
	Resource string
}

CreateParams carries the POST /apis fields.

func (*CreateParams) Validate

func (p *CreateParams) Validate() error

Validate enforces the database constraints up front.

type Grant

type Grant struct {
	APIID                      string
	ClientID                   string
	UserDelegatedAccess        bool
	UserDelegatedPermissionIDs []string
	ClientAccess               bool
	ClientPermissionIDs        []string
}

Grant is one stored grant row with its per-subject permission IDs. CIMD access is computed, not stored: an API-level flag plus the per-permission allowlist (see SetCIMDAccess).

type GrantParams

type GrantParams struct {
	UserDelegatedAccess        bool
	UserDelegatedPermissionIDs []string
	ClientAccess               bool
	ClientPermissionIDs        []string
}

GrantParams is the PUT /apis/{id}/clients/{clientId} payload: access flags plus the granted permission IDs per subject.

type ListParams

type ListParams struct {
	Query string
	Page
}

ListParams narrows and pages the admin listing.

type Page

type Page struct {
	Page  int
	Limit int
}

Page is the store-level paging window: plain ints with no HTTP dependency. The handler converts the request query into it.

func (Page) All

func (p Page) All() bool

All reports whether the listing skips paging (page or limit is the all marker -1).

func (Page) Offset

func (p Page) Offset() int

Offset returns the SQL offset for the current page.

type Permission

type Permission struct {
	ID                    string    `json:"id"`
	APIID                 string    `json:"-"`
	Key                   string    `json:"key"`
	Name                  string    `json:"name"`
	Description           *string   `json:"description,omitzero"`
	AllowedForCIMDClients bool      `json:"allowed_for_cimd_clients"`
	CreatedAt             time.Time `json:"-"`
}

Permission is one scope on an API. The wire scope string is "<resource>:<key>".

type PermissionInput

type PermissionInput struct {
	Key         string
	Name        string
	Description *string
}

PermissionInput is one permission in the list-replace payload.

func (PermissionInput) Validate

func (p PermissionInput) Validate() error

Validate enforces the column constraints.

type PostgresStore

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

PostgresStore persists APIs in public.apis. List-replace writes run inside a WithTx transaction.

func NewPostgresStore

func NewPostgresStore(store datastore.Store) *PostgresStore

NewPostgresStore builds the production API store.

func (*PostgresStore) AllowedScopesForAudience

func (s *PostgresStore) AllowedScopesForAudience(ctx context.Context, clientID, resource string, subjectType string) ([]string, bool, bool, error)

AllowedScopesForAudience resolves an RFC 8707 resource to the permission keys one client may use on it. hasAccess is true when the grant row exists with the matching access flag, even with an empty permission list.

func (*PostgresStore) Create

func (s *PostgresStore) Create(ctx context.Context, params CreateParams) (API, error)

Create inserts an API; uuidv7() fills the ID.

func (*PostgresStore) Delete

func (s *PostgresStore) Delete(ctx context.Context, id APIID) error

Delete removes the API; permissions and grants cascade.

func (*PostgresStore) DeleteGrant

func (s *PostgresStore) DeleteGrant(ctx context.Context, id APIID, clientID string) error

DeleteGrant removes one client's grant on the API.

func (*PostgresStore) GetByID

func (s *PostgresStore) GetByID(ctx context.Context, id APIID) (API, error)

GetByID resolves one API with its permissions.

func (*PostgresStore) GrantFor

func (s *PostgresStore) GrantFor(ctx context.Context, id APIID, clientID string) (Grant, error)

GrantFor resolves one grant; ErrNotFound when the pair is absent.

func (*PostgresStore) List

func (s *PostgresStore) List(ctx context.Context, params ListParams) ([]API, int, error)

List returns matching APIs newest first plus the total count. Permissions are not hydrated here (list views do not need them).

func (*PostgresStore) ListAssignableAPIs

func (s *PostgresStore) ListAssignableAPIs(ctx context.Context, clientID string, params ListParams) ([]API, int, error)

ListAssignableAPIs pages the APIs the client holds no grant on.

func (*PostgresStore) ListAssignableClients

func (s *PostgresStore) ListAssignableClients(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)

ListAssignableClients pages the clients without a grant yet.

func (*PostgresStore) ListClientsWithAccess

func (s *PostgresStore) ListClientsWithAccess(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)

ListClientsWithAccess pages the clients holding a grant on the API.

func (*PostgresStore) ListGrantsForClient

func (s *PostgresStore) ListGrantsForClient(ctx context.Context, clientID string) ([]Grant, error)

ListGrantsForClient lists every grant held by one client.

func (*PostgresStore) SetCIMDAccess

func (s *PostgresStore) SetCIMDAccess(ctx context.Context, id APIID, enabled bool, permissionIDs []string) (API, error)

SetCIMDAccess toggles the API-level flag and replaces the CIMD permission allowlist atomically: listed permissions become CIMD accessible, all others lose the flag.

func (*PostgresStore) SetPermissions

func (s *PostgresStore) SetPermissions(ctx context.Context, id APIID, perms []PermissionInput) ([]Permission, error)

SetPermissions atomically replaces the permission set of one API.

func (*PostgresStore) Update

func (s *PostgresStore) Update(ctx context.Context, id APIID, params UpdateParams) (API, error)

Update patches the name and returns the fresh row.

func (*PostgresStore) UpsertGrant

func (s *PostgresStore) UpsertGrant(ctx context.Context, id APIID, clientID string, params GrantParams) (Grant, error)

UpsertGrant writes the grant flags and replaces the per-subject permission lists atomically. Permission IDs must belong to the API.

type Service

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

Service holds the API registry business rules and HTTP surface.

func NewService

func NewService(store Store, recorder identity.Recorder, opts ...ServiceOption) *Service

NewService builds the feature on the given store.

func (*Service) AllowedScopesForAudience

func (s *Service) AllowedScopesForAudience(ctx context.Context, clientID, resource string, subjectType string) ([]string, bool, bool, error)

AllowedScopesForAudience resolves an RFC 8707 resource to the permission keys one client may use on it. Consumed by the OIDC token paths via the provider adapter in the registry.

func (*Service) AssignableAPIs

func (s *Service) AssignableAPIs(ctx context.Context, clientID string, params ListParams) ([]API, int, error)

AssignableAPIs pages the APIs a client may still be granted.

func (*Service) AssignableClients

func (s *Service) AssignableClients(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)

AssignableClients pages the clients without a grant.

func (*Service) ClientsWithAccess

func (s *Service) ClientsWithAccess(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)

ClientsWithAccess pages the clients holding a grant.

func (*Service) Create

func (s *Service) Create(ctx context.Context, params CreateParams) (API, error)

Create validates and persists a new API.

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, id APIID) error

Delete removes an API; grants and permissions cascade.

func (*Service) DeleteGrant

func (s *Service) DeleteGrant(ctx context.Context, id APIID, clientID string) error

DeleteGrant removes one client's grant on an API.

func (*Service) GetByID

func (s *Service) GetByID(ctx context.Context, id APIID) (API, error)

GetByID resolves one API with permissions.

func (*Service) GrantFor

func (s *Service) GrantFor(ctx context.Context, id APIID, clientID string) (Grant, error)

GrantFor resolves one client's grant on an API.

func (*Service) GrantsForClient

func (s *Service) GrantsForClient(ctx context.Context, clientID string) ([]Grant, error)

GrantsForClient lists every grant held by one client.

func (*Service) List

func (s *Service) List(ctx context.Context, params ListParams) ([]API, int, error)

List returns matching APIs with pagination.

func (*Service) Name

func (s *Service) Name() string

Name names the feature for logs.

func (*Service) RPCService added in v0.0.12

func (s *Service) RPCService() (string, http.Handler)

RPCService returns the Connect registration for the API registry surface.

func (*Service) SetCIMDAccess

func (s *Service) SetCIMDAccess(ctx context.Context, id APIID, enabled bool, permissionIDs []string) (API, error)

SetCIMDAccess toggles the API-level flag plus allowlist.

func (*Service) SetPermissions

func (s *Service) SetPermissions(ctx context.Context, id APIID, perms []PermissionInput) ([]Permission, error)

SetPermissions list-replaces the API's permission set.

func (*Service) Update

func (s *Service) Update(ctx context.Context, id APIID, params UpdateParams) (API, error)

Update patches an API.

func (*Service) UpsertGrant

func (s *Service) UpsertGrant(ctx context.Context, id APIID, clientID string, params GrantParams) (Grant, error)

UpsertGrant writes one client's grant on an API.

type ServiceOption

type ServiceOption func(*Service)

ServiceOption configures the API access feature.

type Store

type Store interface {
	Create(ctx context.Context, params CreateParams) (API, error)
	GetByID(ctx context.Context, id APIID) (API, error)
	Update(ctx context.Context, id APIID, params UpdateParams) (API, error)
	Delete(ctx context.Context, id APIID) error
	List(ctx context.Context, params ListParams) ([]API, int, error)

	SetPermissions(ctx context.Context, id APIID, perms []PermissionInput) ([]Permission, error)

	// Client listing/lookup joins public.oidc_clients; the client
	// ID is the oidc_clients TEXT primary key.
	ListClientsWithAccess(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)
	ListAssignableClients(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)

	GrantFor(ctx context.Context, id APIID, clientID string) (Grant, error)
	UpsertGrant(ctx context.Context, id APIID, clientID string, params GrantParams) (Grant, error)
	DeleteGrant(ctx context.Context, id APIID, clientID string) error
	ListGrantsForClient(ctx context.Context, clientID string) ([]Grant, error)
	ListAssignableAPIs(ctx context.Context, clientID string, params ListParams) ([]API, int, error)

	SetCIMDAccess(ctx context.Context, id APIID, enabled bool, permissionIDs []string) (API, error)

	// AllowedScopesForAudience resolves an RFC 8707 resource to the
	// permission keys one client may use on it, for the OIDC token
	// paths. apiExists false means the resource is unknown. The
	// subject type is a plain string ("user" / "client") to keep
	// this package decoupled from the OIDC surface.
	AllowedScopesForAudience(ctx context.Context, clientID, resource string, subjectType string) (scopes []string, apiExists bool, hasAccess bool, err error)
}

Store abstracts API persistence. Permissions are list-replaced per API; grants are upserted per (api, client) pair.

type SubjectType

type SubjectType string

SubjectType selects which grant side applies: user-delegated flows read user grants; client-credentials reads client grants. String form so the store method satisfies decoupled interfaces.

const (
	SubjectUser   SubjectType = "user"
	SubjectClient SubjectType = "client"
)

type UpdateParams

type UpdateParams struct {
	Name string
}

UpdateParams patches the display name.

func (*UpdateParams) Validate

func (p *UpdateParams) Validate() error

Validate enforces the name constraints.

Jump to

Keyboard shortcuts

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