auth

package
v0.18.4 Latest Latest
Warning

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

Go to latest
Published: Dec 31, 2025 License: Apache-2.0 Imports: 15 Imported by: 1

README

Auth - Authentication and Authorization service

Auth service provides authentication features as an API for managing authentication keys as well as administering groups of entities - clients and users.

Authentication

User service is using Auth service gRPC API to obtain login token or password reset token. Authentication key consists of the following fields:

  • ID - key ID
  • Type - one of the three types described below
  • IssuerID - an ID of the SuperMQ User who issued the key
  • Subject - user ID for which the key is issued
  • IssuedAt - the timestamp when the key is issued
  • ExpiresAt - the timestamp after which the key is invalid

There are four types of authentication keys:

  • Access key - keys issued to the user upon login request
  • Refresh key - keys used to generate new access keys
  • Recovery key - password recovery key
  • API key - keys issued upon the user request
  • Invitation key - keys used to invite new users

Authentication keys are represented and distributed by the corresponding JWT.

User keys are issued when user logs in. Each user request (other than registration and login) contains user key that is used to authenticate the user.

API keys are similar to the User keys. The main difference is that API keys have configurable expiration time. If no time is set, the key will never expire. For that reason, API keys are the only key type that can be revoked. This also means that, despite being used as a JWT, it requires a query to the database to validate the API key. The user with API key can perform all the same actions as the user with login key (can act on behalf of the user for Client, Channel, or user profile management), except issuing new API keys.

Recovery key is the password recovery key. It's short-lived token used for password recovery process.

For in-depth explanation of the aforementioned scenarios, as well as thorough understanding of SuperMQ, please check out the official documentation.

The following actions are supported:

  • create (all key types)
  • verify (all key types)
  • obtain (API keys only)
  • revoke (API keys only)

Domains

Domains are used to group users and clients. Each domain has a unique route that is associated with the domain. Domains are used to group users and their entities.

Domain consists of the following fields:

  • ID - UUID uniquely representing domain
  • Name - name of the domain
  • Tags - array of tags
  • Metadata - Arbitrary, object-encoded domain's data
  • Route - unique route of the domain used in messaging
  • CreatedAt - timestamp at which the domain is created
  • UpdatedAt - timestamp at which the domain is updated
  • UpdatedBy - user that updated the domain
  • CreatedBy - user that created the domain
  • Status - domain status

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

Variable Description Default
SMQ_AUTH_LOG_LEVEL Log level for the Auth service (debug, info, warn, error) info
SMQ_AUTH_DB_HOST Database host address localhost
SMQ_AUTH_DB_PORT Database host port 5432
SMQ_AUTH_DB_USER Database user supermq
SMQ_AUTH_DB_PASSWORD Database password supermq
SMQ_AUTH_DB_NAME Name of the database used by the service auth
SMQ_AUTH_DB_SSL_MODE Database connection SSL mode (disable, require, verify-ca, verify-full) disable
SMQ_AUTH_DB_SSL_CERT Path to the PEM encoded certificate file ""
SMQ_AUTH_DB_SSL_KEY Path to the PEM encoded key file ""
SMQ_AUTH_DB_SSL_ROOT_CERT Path to the PEM encoded root certificate file ""
SMQ_AUTH_HTTP_HOST Auth service HTTP host ""
SMQ_AUTH_HTTP_PORT Auth service HTTP port 8189
SMQ_AUTH_HTTP_SERVER_CERT Path to the PEM encoded HTTP server certificate file ""
SMQ_AUTH_HTTP_SERVER_KEY Path to the PEM encoded HTTP server key file ""
SMQ_AUTH_GRPC_HOST Auth service gRPC host ""
SMQ_AUTH_GRPC_PORT Auth service gRPC port 8181
SMQ_AUTH_GRPC_SERVER_CERT Path to the PEM encoded gRPC server certificate file ""
SMQ_AUTH_GRPC_SERVER_KEY Path to the PEM encoded gRPC server key file ""
SMQ_AUTH_GRPC_SERVER_CA_CERTS Path to the PEM encoded gRPC server CA certificate file ""
SMQ_AUTH_GRPC_CLIENT_CA_CERTS Path to the PEM encoded gRPC client CA certificate file ""
SMQ_AUTH_SECRET_KEY String used for signing tokens secret
SMQ_AUTH_ACCESS_TOKEN_DURATION The access token expiration period 1h
SMQ_AUTH_REFRESH_TOKEN_DURATION The refresh token expiration period 24h
SMQ_AUTH_INVITATION_DURATION The invitation token expiration period 168h
SMQ_AUTH_CACHE_URL Redis URL for caching PAT scopes redis://localhost:6379/0
SMQ_AUTH_CACHE_KEY_DURATION Duration for which PAT scope cache keys are valid 10m
SMQ_SPICEDB_HOST SpiceDB host address localhost
SMQ_SPICEDB_PORT SpiceDB host port 50051
SMQ_SPICEDB_PRE_SHARED_KEY SpiceDB pre-shared key 12345678
SMQ_SPICEDB_SCHEMA_FILE Path to SpiceDB schema file ./docker/spicedb/schema.zed
SMQ_JAEGER_URL Jaeger server URL http://jaeger:4318/v1/traces
SMQ_JAEGER_TRACE_RATIO Jaeger sampling ratio 1.0
SMQ_SEND_TELEMETRY Send telemetry to supermq call home server true
SMQ_ADAPTER_INSTANCE_ID Adapter instance ID ""
SMQ_CALLOUT_URLS Comma-separated list of callout URLs ""
SMQ_CALLOUT_METHOD Callout method POST
SMQ_CALLOUT_TLS_VERIFICATION Enable TLS verification for callouts true
SMQ_CALLOUT_TIMEOUT Callout timeout 10s
SMQ_CALLOUT_CA_CERT Path to CA certificate file ""
SMQ_CALLOUT_CERT Path to client certificate file ""
SMQ_CALLOUT_KEY Path to client key file ""
SMQ_CALLOUT_OPERATIONS Invoke callout if the authorization permission matches any of the given permissions. ""

Deployment

The service itself is distributed as Docker container. Check the auth service section in docker-compose file to see how service is deployed.

Running this service outside of container requires working instance of the postgres database, SpiceDB, and Jaeger server. To start the service outside of the container, execute the following shell script:

# download the latest version of the service
git clone https://github.com/absmach/supermq

cd supermq

# compile the service
make auth

# copy binary to bin
make install

# set the environment variables and run the service
SMQ_AUTH_LOG_LEVEL=info \
SMQ_AUTH_DB_HOST=localhost \
SMQ_AUTH_DB_PORT=5432 \
SMQ_AUTH_DB_USER=supermq \
SMQ_AUTH_DB_PASSWORD=supermq \
SMQ_AUTH_DB_NAME=auth \
SMQ_AUTH_DB_SSL_MODE=disable \
SMQ_AUTH_DB_SSL_CERT="" \
SMQ_AUTH_DB_SSL_KEY="" \
SMQ_AUTH_DB_SSL_ROOT_CERT="" \
SMQ_AUTH_HTTP_HOST=localhost \
SMQ_AUTH_HTTP_PORT=8189 \
SMQ_AUTH_HTTP_SERVER_CERT="" \
SMQ_AUTH_HTTP_SERVER_KEY="" \
SMQ_AUTH_GRPC_HOST=localhost \
SMQ_AUTH_GRPC_PORT=8181 \
SMQ_AUTH_GRPC_SERVER_CERT="" \
SMQ_AUTH_GRPC_SERVER_KEY="" \
SMQ_AUTH_GRPC_SERVER_CA_CERTS="" \
SMQ_AUTH_GRPC_CLIENT_CA_CERTS="" \
SMQ_AUTH_SECRET_KEY=secret \
SMQ_AUTH_ACCESS_TOKEN_DURATION=1h \
SMQ_AUTH_REFRESH_TOKEN_DURATION=24h \
SMQ_AUTH_INVITATION_DURATION=168h \
SMQ_SPICEDB_HOST=localhost \
SMQ_SPICEDB_PORT=50051 \
SMQ_SPICEDB_PRE_SHARED_KEY=12345678 \
SMQ_SPICEDB_SCHEMA_FILE=./docker/spicedb/schema.zed \
SMQ_JAEGER_URL=http://localhost:14268/api/traces \
SMQ_JAEGER_TRACE_RATIO=1.0 \
SMQ_SEND_TELEMETRY=true \
SMQ_AUTH_ADAPTER_INSTANCE_ID="" \
SMQ_CALLOUT_URLS="" \
SMQ_CALLOUT_METHOD="POST" \
SMQ_CALLOUT_TLS_VERIFICATION=true \
$GOBIN/supermq-auth

Setting SMQ_AUTH_HTTP_SERVER_CERT and SMQ_AUTH_HTTP_SERVER_KEY will enable TLS against the service. The service expects a file in PEM format for both the certificate and the key. Setting SMQ_AUTH_GRPC_SERVER_CERT and SMQ_AUTH_GRPC_SERVER_KEY will enable TLS against the service. The service expects a file in PEM format for both the certificate and the key. Setting SMQ_AUTH_GRPC_SERVER_CA_CERTS will enable TLS against the service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs. Setting SMQ_AUTH_GRPC_CLIENT_CA_CERTS will enable TLS against the service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs.

Personal Access Tokens (PATs)

Personal Access Tokens (PATs) provide a secure way to authenticate with SuperMQ APIs without using your primary credentials. They are particularly useful for automation, CI/CD pipelines, and integrating with third-party services.

Overview

PATs in SuperMQ are designed with the following features:

  • Scoped Access: Each token can be limited to specific operations on specific resources
  • Expiration Control: Set custom expiration times for tokens
  • Revocable: Tokens can be revoked at any time
  • Auditable: Track when tokens were last used
  • Secure: Tokens are stored as hashes, not in plaintext
Token Structure

A PAT consists of three parts separated by underscores:

pat_<encoded-user-and-pat-id>_<random-string>

Where:

  • pat is a fixed prefix
  • <encoded-user-and-pat-id> is a base64-encoded combination of the user ID and PAT ID
  • <random-string> is a randomly generated string for additional security
PAT Operations

SuperMQ supports the following operations for PATs:

Operation Description
create Create a new resource
read Read/view a resource
list List resources
update Update/modify a resource
delete Delete a resource
share Share a resource with others
unshare Remove sharing permissions
publish Publish messages to a channel
subscribe Subscribe to messages from a channel
Entity Types

PATs can be scoped to the following entity types:

Entity Type Description
groups User groups
channels Communication channels
clients Client applications
domains Organizational domains
users User accounts
dashboards Dashboard interfaces
messages Message content
API Examples
Creating a PAT
curl --location 'http://localhost:9001/pats' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--data '{
    "name": "test pat",
    "description": "testing pat",
    "duration": "24h"
}'

Response:

{
  "id": "a2500226-95dc-4285-87e2-e693e4a0a976",
  "user_id": "user123",
  "name": "pat 1",
  "description": "for creating any client or channel",
  "secret": "pat_dXNlcjEyM19hMjUwMDIyNi05NWRjLTQyODUtODdlMi1lNjkzZTRhMGE5NzY=_randomstring...",
  "issued_at": "2025-02-27T11:20:59Z",
  "expires_at": "2025-02-28T11:20:59Z"
}
Adding Scopes to a PAT
curl --location --request PATCH 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/scope/add' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--data '{
    "scopes": [
        {
            "optional_domain_id": "c16c980a-9d4c-4793-8fb2-c81304cf1d9f",
            "entity_type": "clients",
            "operation": "create",
            "entity_id": "*"
        },
        {
            "optional_domain_id": "c16c980a-9d4c-4793-8fb2-c81304cf1d9f",
            "entity_type": "channels",
            "operation": "create",
            "entity_id": "cfbc6936-5748-4339-a8ef-37b64b02bc96"
        },
        {
            "entity_type": "dashboards",
            "optional_domain_id": "c16c980a-9d4c-4793-8fb2-c81304cf1d9f",
            "operation": "read",
            "entity_id": "*"
        }
    ]
}'
Listing PATs
curl --location 'http://localhost:9001/pats' \
--header 'Authorization: Bearer <access_token>'
Listing Scopes for a PAT
curl --location 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/scopes' \
--header 'Authorization: Bearer <access_token>'
Revoking a PAT
curl --location --request PATCH 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/revoke' \
--header 'Authorization: Bearer <access_token>'
Resetting a PAT Secret
curl --location --request PATCH 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/reset' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--data '{
    "duration": "720h"
}'
Using PATs for Authentication

When making API requests, include the PAT in the Authorization header:

Authorization: Bearer pat_<encoded-user-and-pat-id>_<random-string>
Example: Creating a Client Using PAT
curl --location 'http://localhost:9006/c16c980a-9d4c-4793-8fb2-c81304cf1d9f/clients' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer pat_etKoiXKTR6a0zdgsBHC00qJQAiaV3EKFh+Lmk+SgqXY=_u7@5fyjgti9V@#Bw^bS*SPmX3OnH=HTvKwmIbxIuyBjoI|6FASo9egjKD^u-M$b|2Dpt3CXZtv&4k+hmYYjk&C$57AV59P%-iDV0' \
--data '{
  "name": "test client",
  "tags": [
    "tag1",
    "tag2"
  ],
  "metadata":{"units":"km"},
  "status": "enabled"
}'

This example shows how to create a client in a specific domain (c16c980a-9d4c-4793-8fb2-c81304cf1d9f) using a PAT for authentication. The PAT must have the appropriate scope (e.g., clients entity type with create operation) for this domain.

Wildcard Entity IDs

When defining scopes for PATs, you can use the wildcard character * for the entity_id field to grant permissions for all entities of a specific type. This is particularly useful for automation tasks that need to operate on multiple resources.

For example:

  • "entity_id": "*" - Grants permission for all entities of the specified type
  • "entity_id": "specific-id" - Grants permission only for the entity with the specified ID

Using wildcards should be done carefully, as they grant broader permissions. Always follow the principle of least privilege by granting only the permissions necessary for the intended use case.

Scope Examples
Allow Creating Any Client in a Domain
{
  "optional_domain_id": "domain_id",
  "entity_type": "clients",
  "operation": "create",
  "entity_id": "*"
}

This scope allows the PAT to create any client within the specified domain. The wildcard * for entity_id means the token can create any client, not just a specific one.

Allow Publishing to a Specific Channel
{
  "optional_domain_id": "domain_id",
  "entity_type": "channels",
  "operation": "publish",
  "entity_id": "channel_id"
}

This scope restricts the PAT to only publish to a specific channel (channel_id) within the specified domain. No wildcard is used, so the permission is limited to just this one channel.

Allow Reading All Dashboards
{
  "optional_domain_id": "domain_id",
  "entity_type": "dashboards",
  "operation": "read",
  "entity_id": "*"
}

This scope allows the PAT to read all dashboards within the specified domain. The wildcard * for entity_id means the token can read any dashboard in that domain.

Best Practices
  1. Limit Scope: Always use the principle of least privilege when creating PATs
  2. Set Expirations: Use reasonable expiration times for tokens
  3. Rotate Regularly: Reset token secrets periodically
  4. Audit Usage: Monitor when tokens are used
  5. Revoke Unused: Remove tokens that are no longer needed
Implementation Details

PATs are stored in the database with the following schema:

CREATE TABLE IF NOT EXISTS pats (
    id              VARCHAR(36) PRIMARY KEY,
    name            VARCHAR(254) NOT NULL,
    user_id         VARCHAR(36),
    description     TEXT,
    secret          TEXT,
    issued_at       TIMESTAMPTZ,
    expires_at      TIMESTAMPTZ,
    updated_at      TIMESTAMPTZ,
    revoked         BOOLEAN,
    revoked_at      TIMESTAMPTZ,
    last_used_at    TIMESTAMPTZ,
    UNIQUE          (id, name, secret)
)

CREATE TABLE IF NOT EXISTS pat_scopes (
    id                  VARCHAR(36) PRIMARY KEY,
    pat_id              VARCHAR(36) REFERENCES pats(id) ON DELETE CASCADE,
    optional_domain_id  VARCHAR(36),
    entity_type         VARCHAR(50) NOT NULL,
    operation           VARCHAR(50) NOT NULL,
    entity_id           VARCHAR(50) NOT NULL,
    UNIQUE (pat_id, optional_domain_id, entity_type, operation, entity_id)
)
Authorization

When a PAT is used for authentication:

  1. The system parses the token to extract the user ID and PAT ID
  2. It verifies the token hasn't been revoked or expired
  3. It checks if the requested operation is allowed by the token's scopes
  4. If all checks pass, the operation is authorized

Usage

For more information about service capabilities and its usage, please check out the API documentation.

Documentation

Index

Constants

View Source
const (
	UnshareOpStr   = "unshare"
	PublishOpStr   = "publish"
	SubscribeOpStr = "subscribe"
)
View Source
const (
	GroupsScopeStr   = "groups"
	ChannelsScopeStr = "channels"
	ClientsScopeStr  = "clients"
	DomainsStr       = "domains"
	UsersStr         = "users"
	DashboardsStr    = "dashboards"
	MessagesStr      = "messages"
)
View Source
const (
	AccessTokenType uint32 = iota
	PersonalAccessTokenType
)
View Source
const (
	Active  = "active"
	Revoked = "revoked"
	Expired = "expired"
	All     = "all"
	Unknown = "unknown"
)
View Source
const AnyIDs = "*"

Variables

View Source
var (
	ErrUnsupportedKeyAlgorithm = errors.New("unsupported key algorithm")
	ErrInvalidSymmetricKey     = errors.New("invalid symmetric key")
	ErrPublicKeysNotSupported  = errors.New("public keys not supported for symmetric algorithm")
)
View Source
var (
	// ErrExpiry indicates that the token is expired.
	ErrExpiry = errors.New("token is expired")
)
View Source
var ErrKeyExpired = errors.New("use of expired key")

ErrKeyExpired indicates that the Key is expired.

Functions

func DecodeDomainUserID

func DecodeDomainUserID(domainUserID string) (string, string)

func EncodeDomainUserID

func EncodeDomainUserID(domainID, userID string) string

func IsSymmetricAlgorithm added in v0.18.4

func IsSymmetricAlgorithm(alg string) (bool, error)

IsSymmetricAlgorithm determines if the given algorithm is symmetric (HMAC-based). Returns true for HMAC algorithms (HS256, HS384, HS512). Returns false for asymmetric algorithms (EdDSA). Returns error for unsupported algorithms.

func SwitchToPermission

func SwitchToPermission(relation string) string

Switch the relative permission for the relation.

Types

type Authn

type Authn interface {
	// Issue issues a new Key, returning its token value alongside.
	Issue(ctx context.Context, token string, key Key) (Token, error)

	// Revoke removes the Key with the provided id that is
	// issued by the user identified by the provided key.
	Revoke(ctx context.Context, token, id string) error

	// RetrieveKey retrieves data for the Key identified by the provided
	// ID, that is issued by the user identified by the provided key.
	RetrieveKey(ctx context.Context, token, id string) (Key, error)

	// Identify validates token token. If token is valid, content
	// is returned. If token is invalid, or invocation failed for some
	// other reason, non-nil error value is returned in response.
	Identify(ctx context.Context, token string) (Key, error)

	// RetrieveJWKS retrieves public keys to validate issued tokens.
	RetrieveJWKS() []PublicKeyInfo
}

Authn specifies an API that must be fulfilled by the domain service implementation, and all of its decorators (e.g. logging & metrics). Token is a string value of the actual Key and is used to authenticate an Auth service request.

type Authz

type Authz interface {
	// Authorize checks authorization of the given `subject`. Basically,
	// Authorize verifies that Is `subject` allowed to `relation` on
	// `object`. Authorize returns a non-nil error if the subject has
	// no relation on the object (which simply means the operation is
	// denied).
	Authorize(ctx context.Context, pr policies.Policy) error
}

Authz represents a authorization service. It exposes functionalities through `auth` to perform authorization.

type Cache added in v0.17.0

type Cache interface {
	Save(ctx context.Context, userID string, scopes []Scope) error

	CheckScope(ctx context.Context, userID, patID, optionalDomainID string, entityType EntityType, operation Operation, entityID string) bool

	Remove(ctx context.Context, userID string, scopesID []string) error

	RemoveUserAllScope(ctx context.Context, userID string) error

	RemoveAllScope(ctx context.Context, userID, patID string) error
}

type EntityType added in v0.17.0

type EntityType uint32
const (
	GroupsType EntityType = iota
	ChannelsType
	ClientsType
	DomainsType
	UsersType
	DashboardType
	MessagesType
)

func ParseEntityType added in v0.17.0

func ParseEntityType(et string) (EntityType, error)

func (EntityType) MarshalJSON added in v0.17.0

func (et EntityType) MarshalJSON() ([]byte, error)

func (EntityType) MarshalText added in v0.17.0

func (et EntityType) MarshalText() ([]byte, error)

func (EntityType) String added in v0.17.0

func (et EntityType) String() string

func (*EntityType) UnmarshalJSON added in v0.17.0

func (et *EntityType) UnmarshalJSON(data []byte) error

func (*EntityType) UnmarshalText added in v0.17.0

func (et *EntityType) UnmarshalText(data []byte) (err error)

func (EntityType) ValidString added in v0.17.0

func (et EntityType) ValidString() (string, error)

type Hasher added in v0.17.0

type Hasher interface {
	// Hash generates the hashed string from plain-text.
	Hash(string) (string, error)

	// Compare compares plain-text version to the hashed one. An error should
	// indicate failed comparison.
	Compare(string, string) error
}

Hasher specifies an API for generating hashes of an arbitrary textual content.

type Key

type Key struct {
	ID        string    `json:"id,omitempty"`
	Type      KeyType   `json:"type,omitempty"`
	Issuer    string    `json:"issuer,omitempty"`
	Subject   string    `json:"subject,omitempty"` // user ID
	Role      Role      `json:"role,omitempty"`
	IssuedAt  time.Time `json:"issued_at,omitempty"`
	ExpiresAt time.Time `json:"expires_at,omitempty"`
	Verified  bool      `json:"verified,omitempty"`
}

Key represents API key.

func (Key) Expired

func (key Key) Expired() bool

Expired verifies if the key is expired.

func (Key) String

func (key Key) String() string

type KeyRepository

type KeyRepository interface {
	// Save persists the Key. A non-nil error is returned to indicate
	// operation failure
	Save(ctx context.Context, key Key) (id string, err error)

	// Retrieve retrieves Key by its unique identifier.
	Retrieve(ctx context.Context, issuer string, id string) (key Key, err error)

	// Remove removes Key with provided ID.
	Remove(ctx context.Context, issuer string, id string) error
}

KeyRepository specifies Key persistence API.

type KeyType

type KeyType uint32
const (
	// AccessKey is temporary User key received on successful login.
	AccessKey KeyType = iota
	// RefreshKey is a temporary User key used to generate a new access key.
	RefreshKey
	// RecoveryKey represents a key for resseting password.
	RecoveryKey
	// APIKey enables the one to act on behalf of the user.
	APIKey
	// PersonalAccessToken represents token generated by user for automation.
	PersonalAccessToken
	// InvitationKey is a key for inviting new users.
	InvitationKey
)

func (KeyType) String

func (kt KeyType) String() string

func (KeyType) Validate added in v0.17.0

func (kt KeyType) Validate() bool

type Operation added in v0.17.0

type Operation uint32
const (
	CreateOp Operation = iota
	ReadOp
	ListOp
	UpdateOp
	DeleteOp
	ShareOp
	UnshareOp
	PublishOp
	SubscribeOp
)

func ParseOperation added in v0.17.0

func ParseOperation(op string) (Operation, error)

func (Operation) MarshalJSON added in v0.17.0

func (op Operation) MarshalJSON() ([]byte, error)

func (Operation) MarshalText added in v0.17.0

func (op Operation) MarshalText() (text []byte, err error)

func (Operation) String added in v0.17.0

func (op Operation) String() string

func (*Operation) UnmarshalJSON added in v0.17.0

func (op *Operation) UnmarshalJSON(data []byte) error

func (*Operation) UnmarshalText added in v0.17.0

func (op *Operation) UnmarshalText(data []byte) (err error)

func (Operation) ValidString added in v0.17.0

func (op Operation) ValidString() (string, error)

type PAT added in v0.17.0

type PAT struct {
	ID          string    `json:"id,omitempty"`
	User        string    `json:"user_id,omitempty"`
	Name        string    `json:"name,omitempty"`
	Description string    `json:"description,omitempty"`
	Secret      string    `json:"secret,omitempty"`
	Role        Role      `json:"role,omitempty"`
	IssuedAt    time.Time `json:"issued_at,omitempty"`
	ExpiresAt   time.Time `json:"expires_at,omitempty"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"`
	LastUsedAt  time.Time `json:"last_used_at,omitempty"`
	Revoked     bool      `json:"revoked,omitempty"`
	RevokedAt   time.Time `json:"revoked_at,omitempty"`
	Status      Status    `json:"status,omitempty"`
}

PAT represents Personal Access Token.

func (PAT) MarshalBinary added in v0.17.0

func (pat PAT) MarshalBinary() ([]byte, error)

func (PAT) MarshalJSON added in v0.17.0

func (p PAT) MarshalJSON() ([]byte, error)

func (*PAT) String added in v0.17.0

func (pat *PAT) String() string

func (*PAT) UnmarshalBinary added in v0.17.0

func (pat *PAT) UnmarshalBinary(data []byte) error

func (*PAT) Validate added in v0.18.0

func (pat *PAT) Validate() error

Validate checks if the PAT has valid fields.

type PATS added in v0.17.0

type PATS interface {
	// Create function creates new PAT for given valid inputs.
	CreatePAT(ctx context.Context, token, name, description string, duration time.Duration) (PAT, error)

	// UpdateName function updates the name for the given PAT ID.
	UpdatePATName(ctx context.Context, token, patID, name string) (PAT, error)

	// UpdateDescription function updates the description for the given PAT ID.
	UpdatePATDescription(ctx context.Context, token, patID, description string) (PAT, error)

	// Retrieve function retrieves the PAT for given ID.
	RetrievePAT(ctx context.Context, userID string, patID string) (PAT, error)

	// RemoveAllPAT function removes all PATs of user.
	RemoveAllPAT(ctx context.Context, token string) error

	// ListPATS function lists all the PATs for the user.
	ListPATS(ctx context.Context, token string, pm PATSPageMeta) (PATSPage, error)

	// Delete function deletes the PAT for given ID.
	DeletePAT(ctx context.Context, token, patID string) error

	// ResetSecret function reset the secret and creates new secret for the given ID.
	ResetPATSecret(ctx context.Context, token, patID string, duration time.Duration) (PAT, error)

	// RevokeSecret function revokes the secret for the given ID.
	RevokePATSecret(ctx context.Context, token, patID string) error

	// AddScope function adds a new scope.
	AddScope(ctx context.Context, token, patID string, scopes []Scope) error

	// RemoveScope function removes a scope.
	RemoveScope(ctx context.Context, token string, patID string, scopeIDs ...string) error

	// RemovePATAllScope function removes all scope.
	RemovePATAllScope(ctx context.Context, token, patID string) error

	// List function lists all the Scopes for the patID.
	ListScopes(ctx context.Context, token string, pm ScopesPageMeta) (ScopesPage, error)

	// IdentifyPAT function will valid the secret.
	IdentifyPAT(ctx context.Context, paToken string) (PAT, error)

	// AuthorizePAT function will valid the secret and check the given scope exists.
	AuthorizePAT(ctx context.Context, userID, patID string, entityType EntityType, optionalDomainID string, operation Operation, entityID string) error
}

PATS specifies function which are required for Personal access Token implementation.

type PATSPage added in v0.17.0

type PATSPage struct {
	Total  uint64 `json:"total"`
	Offset uint64 `json:"offset"`
	Limit  uint64 `json:"limit"`
	PATS   []PAT  `json:"pats"`
}

type PATSPageMeta added in v0.17.0

type PATSPageMeta struct {
	Offset uint64 `json:"offset"`
	Limit  uint64 `json:"limit"`
	Name   string `json:"name"`
	ID     string `json:"id"`
	Status Status `json:"status"`
}

type PATSRepository added in v0.17.0

type PATSRepository interface {
	// Save persists the PAT
	Save(ctx context.Context, pat PAT) (err error)

	// Retrieve retrieves users PAT by its unique identifier.
	Retrieve(ctx context.Context, userID, patID string) (pat PAT, err error)

	// RetrieveScope retrieves PAT scopes by its unique identifier.
	RetrieveScope(ctx context.Context, pm ScopesPageMeta) (scopes ScopesPage, err error)

	// RetrieveSecretAndRevokeStatus retrieves secret and revoke status of PAT by its unique identifier.
	RetrieveSecretAndRevokeStatus(ctx context.Context, userID, patID string) (string, bool, bool, error)

	// UpdateName updates the name of a PAT.
	UpdateName(ctx context.Context, userID, patID, name string) (PAT, error)

	// UpdateDescription updates the description of a PAT.
	UpdateDescription(ctx context.Context, userID, patID, description string) (PAT, error)

	// UpdateTokenHash updates the token hash of a PAT.
	UpdateTokenHash(ctx context.Context, userID, patID, tokenHash string, expiryAt time.Time) (PAT, error)

	// RetrieveAll retrieves all PATs belongs to userID.
	RetrieveAll(ctx context.Context, userID string, pm PATSPageMeta) (pats PATSPage, err error)

	// Revoke PAT with provided ID.
	Revoke(ctx context.Context, userID, patID string) error

	// Reactivate PAT with provided ID.
	Reactivate(ctx context.Context, userID, patID string) error

	// Remove removes Key with provided ID.
	Remove(ctx context.Context, userID, patID string) error

	// RemoveAllPAT removes all PAT for a given user.
	RemoveAllPAT(ctx context.Context, userID string) error

	AddScope(ctx context.Context, userID string, scopes []Scope) error

	RemoveScope(ctx context.Context, userID string, scopesIDs ...string) error

	CheckScope(ctx context.Context, userID, patID string, entityType EntityType, optionalDomainID string, operation Operation, entityID string) error

	RemoveAllScope(ctx context.Context, patID string) error
}

PATSRepository specifies PATS persistence API.

type PublicKeyInfo added in v0.18.4

type PublicKeyInfo struct {
	KeyID     string `json:"kid"`
	KeyType   string `json:"kty"`
	Algorithm string `json:"alg"`
	Use       string `json:"use,omitempty"`

	// EdDSA (Ed25519) fields
	Curve string `json:"crv,omitempty"`
	X     string `json:"x,omitempty"`
}

PublicKeyInfo represents a public key for external distribution via JWKS. This follows RFC 7517 (JSON Web Key) specification.

type Role added in v0.17.0

type Role uint32
const (
	UserRole Role = iota + 1
	AdminRole
)

func (Role) String added in v0.17.0

func (r Role) String() string

func (Role) Validate added in v0.17.0

func (r Role) Validate() bool

type Scope added in v0.17.0

type Scope struct {
	ID               string     `json:"id"`
	PatID            string     `json:"pat_id"`
	OptionalDomainID string     `json:"optional_domain_id"`
	EntityType       EntityType `json:"entity_type"`
	EntityID         string     `json:"entity_id"`
	Operation        Operation  `json:"operation"`
}

func (*Scope) Authorized added in v0.17.0

func (s *Scope) Authorized(entityType EntityType, optionalDomainID string, operation Operation, entityID string) bool

func (*Scope) Validate added in v0.17.0

func (s *Scope) Validate() error

type ScopesPage added in v0.17.0

type ScopesPage struct {
	Total  uint64  `json:"total"`
	Offset uint64  `json:"offset"`
	Limit  uint64  `json:"limit"`
	Scopes []Scope `json:"scopes"`
}

type ScopesPageMeta added in v0.17.0

type ScopesPageMeta struct {
	Offset uint64 `json:"offset"`
	Limit  uint64 `json:"limit"`
	PatID  string `json:"pat_id"`
	ID     string `json:"id"`
}

type Service

type Service interface {
	Authn
	Authz
	PATS
}

Service specifies an API that must be fulfilled by the domain service implementation, and all of its decorators (e.g. logging & metrics). Token is a string value of the actual Key and is used to authenticate an Auth service request.

func New

func New(keys KeyRepository, pats PATSRepository, cache Cache, hasher Hasher, idp supermq.IDProvider, tokenizer Tokenizer, policyEvaluator policies.Evaluator, policyService policies.Service, loginDuration, refreshDuration, invitationDuration time.Duration) Service

New instantiates the auth service implementation.

type Status added in v0.17.0

type Status uint8
const (
	ActiveStatus Status = iota
	RevokedStatus
	ExpiredStatus
	AllStatus
)

func ToStatus added in v0.17.0

func ToStatus(status string) (Status, error)

ToStatus converts string value to a valid Client status.

func (Status) MarshalJSON added in v0.17.0

func (s Status) MarshalJSON() ([]byte, error)

func (Status) String added in v0.17.0

func (s Status) String() string

func (*Status) UnmarshalJSON added in v0.17.0

func (s *Status) UnmarshalJSON(data []byte) error

type Token

type Token struct {
	AccessToken  string // AccessToken contains the security credentials for a login session and identifies the client.
	RefreshToken string // RefreshToken is a credential artifact that OAuth can use to get a new access token without client interaction.
	AccessType   string // AccessType is the specific type of access token issued. It can be Bearer, Client or Basic.
}

type Tokenizer

type Tokenizer interface {
	// Issue creates a signed token string from the given key claims.
	Issue(key Key) (token string, err error)

	// Parse verifies and parses a token string (JWT or PAT), returning the extracted claims.
	// For PAT tokens (prefix "pat"), returns a Key with Type set to PersonalAccessToken.
	// For JWT tokens, performs cryptographic verification and returns the parsed claims.
	Parse(ctx context.Context, token string) (key Key, err error)

	// RetrieveJWKS returns public keys for distribution via JWKS endpoint.
	// Returns ErrPublicKeysNotSupported for symmetric tokenizers (HMAC).
	RetrieveJWKS() ([]PublicKeyInfo, error)
}

Tokenizer handles token creation and verification for authentication. Implementations manage underlying cryptographic operations and key distribution.

Directories

Path Synopsis
api
Package api contains implementation of Auth service HTTP API.
Package api contains implementation of Auth service HTTP API.
grpc/auth
Package auth contains implementation of Auth service gRPC API.
Package auth contains implementation of Auth service gRPC API.
grpc/token
Package grpc contains implementation of Auth service gRPC API.
Package grpc contains implementation of Auth service gRPC API.
Package hasher contains the domain concept definitions needed to support Supermq users password hasher sub-service functionality.
Package hasher contains the domain concept definitions needed to support Supermq users password hasher sub-service functionality.
Package middleware provides logging metrics and tracing middleware for SuperMQ Auth service.
Package middleware provides logging metrics and tracing middleware for SuperMQ Auth service.
Package postgres contains Key repository implementations using PostgreSQL as the underlying database.
Package postgres contains Key repository implementations using PostgreSQL as the underlying database.
tokenizer

Jump to

Keyboard shortcuts

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