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 ¶
- Variables
- type API
- type APIID
- type ClientRef
- type CreateParams
- type Grant
- type GrantParams
- type ListParams
- type Page
- type Permission
- type PermissionInput
- type PostgresStore
- func (s *PostgresStore) AllowedScopesForAudience(ctx context.Context, clientID, resource string, subjectType string) ([]string, bool, bool, error)
- func (s *PostgresStore) Create(ctx context.Context, params CreateParams) (API, error)
- func (s *PostgresStore) Delete(ctx context.Context, id APIID) error
- func (s *PostgresStore) DeleteGrant(ctx context.Context, id APIID, clientID string) error
- func (s *PostgresStore) GetByID(ctx context.Context, id APIID) (API, error)
- func (s *PostgresStore) GrantFor(ctx context.Context, id APIID, clientID string) (Grant, error)
- func (s *PostgresStore) List(ctx context.Context, params ListParams) ([]API, int, error)
- func (s *PostgresStore) ListAssignableAPIs(ctx context.Context, clientID string, params ListParams) ([]API, int, error)
- func (s *PostgresStore) ListAssignableClients(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)
- func (s *PostgresStore) ListClientsWithAccess(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)
- func (s *PostgresStore) ListGrantsForClient(ctx context.Context, clientID string) ([]Grant, error)
- func (s *PostgresStore) SetCIMDAccess(ctx context.Context, id APIID, enabled bool, permissionIDs []string) (API, error)
- func (s *PostgresStore) SetPermissions(ctx context.Context, id APIID, perms []PermissionInput) ([]Permission, error)
- func (s *PostgresStore) Update(ctx context.Context, id APIID, params UpdateParams) (API, error)
- func (s *PostgresStore) UpsertGrant(ctx context.Context, id APIID, clientID string, params GrantParams) (Grant, error)
- type Service
- func (s *Service) AllowedScopesForAudience(ctx context.Context, clientID, resource string, subjectType string) ([]string, bool, bool, error)
- func (s *Service) AssignableAPIs(ctx context.Context, clientID string, params ListParams) ([]API, int, error)
- func (s *Service) AssignableClients(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)
- func (s *Service) ClientsWithAccess(ctx context.Context, id APIID, params ListParams) ([]ClientRef, int, error)
- func (s *Service) Create(ctx context.Context, params CreateParams) (API, error)
- func (s *Service) Delete(ctx context.Context, id APIID) error
- func (s *Service) DeleteGrant(ctx context.Context, id APIID, clientID string) error
- func (s *Service) GetByID(ctx context.Context, id APIID) (API, error)
- func (s *Service) GrantFor(ctx context.Context, id APIID, clientID string) (Grant, error)
- func (s *Service) GrantsForClient(ctx context.Context, clientID string) ([]Grant, error)
- func (s *Service) List(ctx context.Context, params ListParams) ([]API, int, error)
- func (s *Service) Name() string
- func (s *Service) RPCService() (string, http.Handler)
- func (s *Service) SetCIMDAccess(ctx context.Context, id APIID, enabled bool, permissionIDs []string) (API, error)
- func (s *Service) SetPermissions(ctx context.Context, id APIID, perms []PermissionInput) ([]Permission, error)
- func (s *Service) Update(ctx context.Context, id APIID, params UpdateParams) (API, error)
- func (s *Service) UpsertGrant(ctx context.Context, id APIID, clientID string, params GrantParams) (Grant, error)
- type ServiceOption
- type Store
- type SubjectType
- type UpdateParams
Constants ¶
This section is empty.
Variables ¶
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 ¶
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"`
HasLogo bool `json:"has_logo"`
}
ClientRef is the apiClientDto shape: the OIDC client subset the API admin UI renders.
type CreateParams ¶
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 ¶
ListParams narrows and pages the admin listing.
type Page ¶
Page is the store-level paging window: plain ints with no HTTP dependency. The handler converts the request query into it.
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 ¶
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 ¶
DeleteGrant removes one client's grant on the API.
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 ¶
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) DeleteGrant ¶
DeleteGrant removes one client's grant on an API.
func (*Service) GrantsForClient ¶
GrantsForClient lists every grant held by one client.
func (*Service) RPCService ¶ added in v0.0.12
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) 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.