Documentation
¶
Overview ¶
Package serviceaccount manages service accounts: service principals that belong to one organization, hold application roles there like a member, and authenticate with key pairs through the RFC 7523 JWT-bearer grant (ADR-016).
A service account is a Principal of type service whose organization_id is its organization, with a ServicePrincipal row of service type "service_account" and an active membership in the organization with the role "service_account". Its identifier, "sa_" and 26 random characters, is the issuer and subject of the assertions it signs. SystemAuth stores only its public keys, as key-pair credentials.
Ending access goes through the usual paths and is recorded as an access change (ADR-010): Disable and Delete deactivate the principal (Deactivated), RemoveRole removes an application role (AppRoleChanged), and revoking a usable key records SessionsRevoked.
Index ¶
- Constants
- Variables
- func NewIdentifier() string
- func ParsePublicKeyPEM(s string) (any, error)
- type Account
- type Config
- type CreateInput
- type Key
- type KeyInput
- type PrincipalService
- type Service
- func (s *Service) AddKey(ctx context.Context, id uuid.UUID, in KeyInput) (*Key, error)
- func (s *Service) Create(ctx context.Context, in CreateInput) (*Account, error)
- func (s *Service) Delete(ctx context.Context, id, by uuid.UUID) error
- func (s *Service) Disable(ctx context.Context, id, by uuid.UUID) error
- func (s *Service) Enable(ctx context.Context, id, by uuid.UUID) error
- func (s *Service) Get(ctx context.Context, id uuid.UUID) (*Account, error)
- func (s *Service) GrantRole(ctx context.Context, id uuid.UUID, application, role string, by uuid.UUID) error
- func (s *Service) List(ctx context.Context, organizationID uuid.UUID) ([]*Account, error)
- func (s *Service) ListKeys(ctx context.Context, id uuid.UUID) ([]*Key, error)
- func (s *Service) RemoveRole(ctx context.Context, id uuid.UUID, application string, by uuid.UUID) error
- func (s *Service) RevokeKey(ctx context.Context, id uuid.UUID, keyID, reason string) error
Constants ¶
const ( AlgorithmES256 = "ES256" AlgorithmRS256 = "RS256" AlgorithmEdDSA = "EdDSA" )
Key algorithms a service account key may use.
const ( // MembershipRole is the membership role of a service account in its // organization, shown as "Service account". MembershipRole = "service_account" // ServiceType is the service type of a service account's // ServicePrincipal row. ServiceType = "service_account" // IdentifierPrefix starts every service account identifier. IdentifierPrefix = "sa_" )
const EventServiceAccount = "service_account"
EventServiceAccount is the event type of the security events the service records through Config.Audit. The action says what changed: created, disabled, enabled, deleted, key_added, key_revoked, role_granted or role_removed. No event carries key material.
const MinRSABits = 2048
MinRSABits is the shortest RSA key accepted.
Variables ¶
var ( // ErrNotFound means the ID names no service account. ErrNotFound = errors.New("serviceaccount: service account not found") // ErrKeyNotFound means the account has no key with the key ID. ErrKeyNotFound = errors.New("serviceaccount: key not found") // ErrOrganizationNotFound means the organization does not exist. ErrOrganizationNotFound = errors.New("serviceaccount: organization not found") // ErrOrganizationInactive means the organization was deleted. ErrOrganizationInactive = errors.New("serviceaccount: organization is not active") // ErrPersonalOrganization means the organization is personal, and a // personal organization has no service accounts. ErrPersonalOrganization = errors.New("serviceaccount: a personal organization cannot have service accounts") // ErrNameRequired means CreateInput.Name is empty. ErrNameRequired = errors.New("serviceaccount: name is required") // ErrInvalidKey means a public key cannot be used: unparsable, of an // unsupported type or algorithm, an RSA key shorter than 2048 bits, or // an expiry in the past. ErrInvalidKey = errors.New("serviceaccount: invalid key") )
Errors returned by the service.
Functions ¶
func NewIdentifier ¶
func NewIdentifier() string
NewIdentifier returns a fresh service account identifier: "sa_" and 26 random lowercase base32 characters.
func ParsePublicKeyPEM ¶
ParsePublicKeyPEM parses a PEM "PUBLIC KEY" (PKIX) or "RSA PUBLIC KEY" (PKCS #1) block into an *ecdsa.PublicKey, *rsa.PublicKey or ed25519.PublicKey.
Types ¶
type Account ¶
type Account struct {
ID uuid.UUID `json:"id"`
Identifier string `json:"identifier"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
OrganizationID uuid.UUID `json:"organization_id"`
Active bool `json:"active"`
AllowedScopes []string `json:"allowed_scopes,omitempty"`
CreatedBy *uuid.UUID `json:"created_by,omitempty"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Account is a service account.
type Config ¶
type Config struct {
// Client is the identity database. Required.
Client *ent.Client
// Principals creates, deactivates and reactivates principals. Use the
// host's principal service so authorization syncing and access-change
// announcements follow its options. Required; principal.NewService's
// result implements it.
Principals principal.Service
// Credentials stores key-pair credentials. Default:
// credential.NewService(Client).
Credentials credential.Service
// Roles manages application roles. Required for GrantRole, RemoveRole
// and Delete.
Roles *approle.Service
// AccessChangeSink announces the access changes the service itself
// records (revoking a key) after they commit.
AccessChangeSink accesschange.Sink
// Logger records operator actions. Default: slog.Default().
Logger *slog.Logger
// Audit records security events (EventServiceAccount) for account,
// key and role changes. Optional.
Audit audit.Emitter
}
Config holds the service's dependencies.
type CreateInput ¶
type CreateInput struct {
OrganizationID uuid.UUID
Name string
Description string
// Scopes are the scopes the account may be granted; a token's scopes
// are the requested ones intersected with these and its key's.
Scopes []string
// CreatedBy is the operator's principal ID; uuid.Nil records none.
CreatedBy uuid.UUID
}
CreateInput describes a new service account.
type Key ¶
type Key struct {
CredentialID uuid.UUID `json:"credential_id"`
KeyID string `json:"key_id"`
Algorithm string `json:"algorithm"`
PublicKeyPEM string `json:"public_key_pem"`
Name string `json:"name,omitempty"`
Scopes []string `json:"scopes,omitempty"`
Active bool `json:"active"`
Revoked bool `json:"revoked"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
LastUsedIP string `json:"last_used_ip,omitempty"`
CreatedAt time.Time `json:"created_at"`
// PrivateKeyPEM is the PKCS #8 private key, set only on the Key AddKey
// returns for a generated key pair. It is never stored; it is not
// serialized, so it cannot leak through a JSON listing.
PrivateKeyPEM string `json:"-"`
}
Key is a service account key.
type KeyInput ¶
type KeyInput struct {
// PublicKeyPEM is a PEM "PUBLIC KEY" (PKIX) or "RSA PUBLIC KEY"
// (PKCS #1) block. Empty generates a key pair.
PublicKeyPEM string
// Algorithm is ES256 (P-256), RS256 (RSA, 2048 bits or more) or
// EdDSA (Ed25519). Empty takes it from the key.
Algorithm string
// Name labels the key.
Name string
// Scopes limit the key; empty means the account's allowed scopes.
Scopes []string
// ExpiresAt is when the key stops working; nil means never.
ExpiresAt *time.Time
}
KeyInput describes a key to add. With PublicKeyPEM empty, AddKey generates a P-256 key pair and returns the private key once.
type PrincipalService ¶
type PrincipalService interface {
principal.ServiceTxCreator
Deactivate(ctx context.Context, id uuid.UUID) error
Reactivate(ctx context.Context, id uuid.UUID) error
}
PrincipalService is what the service needs of identity/principal. principal.DefaultService implements it.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service manages service accounts.
func New ¶
New returns a Service. It fails when Client or Principals is missing, or when Principals cannot create a service principal in a transaction.
func (*Service) AddKey ¶
AddKey registers a public key for the account, or generates a P-256 key pair and returns its private key once in Key.PrivateKeyPEM.
func (*Service) Create ¶
Create creates a service account in an active, non-personal organization: the service principal, its ServicePrincipal row recording who created it, and its service_account membership, in one transaction.
The membership is not written to the authorization graph: applications see the account through its application roles and the orgs claim.
func (*Service) Delete ¶
Delete deactivates the account (recording Deactivated if it was active), removes its application roles, then deletes its keys, membership and principal.
func (*Service) Disable ¶
Disable deactivates the account, which records a Deactivated access change: its tokens stop at once in applications with a revocation cache, and no new token is issued.
func (*Service) GrantRole ¶
func (s *Service) GrantRole(ctx context.Context, id uuid.UUID, application, role string, by uuid.UUID) error
GrantRole gives the account a role in an application of its organization, replacing the role it held there.
func (*Service) ListKeys ¶
ListKeys returns the account's keys, newest first, including revoked and expired ones.
func (*Service) RemoveRole ¶
func (s *Service) RemoveRole(ctx context.Context, id uuid.UUID, application string, by uuid.UUID) error
RemoveRole removes the account's role in an application, which records an AppRoleChanged access change.
func (*Service) RevokeKey ¶
RevokeKey revokes one of the account's keys. When the key was usable, a SessionsRevoked access change is recorded with it, so the account's current tokens, which may have been obtained with it, stop at once in applications with a revocation cache; a workload holding another key gets a new token. Revoking a revoked key does nothing.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package serviceaccountcmd provides the "service-account" cobra command a host CLI mounts to manage service accounts: create, list, show, disable, enable and delete accounts; add, list and revoke their keys; and grant and remove their application roles.
|
Package serviceaccountcmd provides the "service-account" cobra command a host CLI mounts to manage service accounts: create, list, show, disable, enable and delete accounts; add, list and revoke their keys; and grant and remove their application roles. |