Documentation
¶
Overview ¶
Package authcore provides a modular, production-ready authentication library for Go.
Quick start ¶
cfg := authcore.DefaultConfig()
auth, err := authcore.New(cfg)
if err != nil {
log.Fatal(err)
}
Modules ¶
Authentication mechanisms live under the auth/ sub-tree. Each module is an independent package that accepts an authcore.Provider — the narrow interface that *AuthCore satisfies — so modules remain independently testable.
auth/jwt — JSON Web Tokens (access + refresh, EdDSA) auth/password — Argon2id password hashing auth/email — email validation and normalization auth/username — username validation and normalization auth/apikey — opaque API key generation and validation auth/oauth — OpenID Connect / OAuth 2.0 client (social login)
Key management ¶
authcore automatically generates and persists cryptographic keys on first run. Keys are stored in Config.KeysDir (default ".authcore") and are protected by a .gitignore so they are never accidentally committed.
Extending authcore ¶
To write a new module, accept a Provider in your constructor and implement the Module interface:
type MyModule struct { ... }
func New(p authcore.Provider, cfg Config) (*MyModule, error) { ... }
func (m *MyModule) Name() string { return "mymodule" }
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidConfig is returned when the supplied Config fails validation. ErrInvalidConfig = errors.New("authcore: invalid configuration") // ErrInvalidTimezone is returned when Config.Timezone is nil. ErrInvalidTimezone = errors.New("authcore: timezone must not be nil") // ErrKeyManager is returned when the key management system fails to // initialise, generate, or load cryptographic material. ErrKeyManager = errors.New("authcore: key manager failure") )
Sentinel errors returned by the authcore package. Use errors.Is to check for these in calling code.
Functions ¶
This section is empty.
Types ¶
type AuthCore ¶
type AuthCore struct {
// contains filtered or unexported fields
}
AuthCore is the central object of the library. It holds shared configuration, the logger, and the key manager, and is the entry point for all authentication sub-modules.
Create one instance per application; it is safe for concurrent use.
func New ¶
New creates and returns a fully initialised *AuthCore.
It applies defaults to any zero-value fields in cfg, validates the result, selects or creates a logger, and initialises the key manager.
On first run the key manager creates Config.KeysDir and generates fresh Ed25519 keys and an HMAC refresh secret. On subsequent runs the existing files are loaded and validated.
New returns a wrapped ErrInvalidConfig on bad configuration, or a wrapped ErrKeyManager when key initialisation fails. Both are unwrappable with errors.Is.
// Minimal — all defaults apply. auth, err := authcore.New(authcore.DefaultConfig()) // Custom keys directory (useful in containers or tests). cfg := authcore.DefaultConfig() cfg.KeysDir = "/run/secrets/authcore" auth, err := authcore.New(cfg)
Example ¶
package main
import (
"fmt"
"os"
"github.com/Glyndor/authcore"
)
func main() {
dir, _ := os.MkdirTemp("", "authcore-example-")
defer func() { _ = os.RemoveAll(dir) }()
cfg := authcore.DefaultConfig()
cfg.EnableLogs = false
cfg.KeysDir = dir
auth, err := authcore.New(cfg)
if err != nil {
panic(err)
}
fmt.Println(auth.Keys() != nil)
}
Output: true
func (*AuthCore) Config ¶
Config returns a copy of the active configuration. Sub-modules should call this to read shared settings.
type Config ¶
type Config struct {
// EnableLogs controls whether the library emits log output.
// Defaults to true.
EnableLogs bool
// Timezone is used for any time-sensitive operations inside the library.
// Defaults to time.UTC.
Timezone *time.Location
// Logger allows callers to inject a custom logging backend
// (e.g. slog, zap, zerolog). When set, EnableLogs is ignored.
// If nil and EnableLogs is true, a default stdlib logger is used.
Logger Logger
// KeysDir is the directory where authcore creates and stores cryptographic
// key files (ed25519_private.pem, ed25519_public.pem, refresh_secret.key).
//
// Defaults to ".authcore" relative to the current working directory.
// Use an absolute path in containerised or restricted environments.
//
// The directory is created automatically on first use. A .gitignore is
// written inside it to prevent accidental commits of key material.
//
// Ignored when KeyStore is set.
KeysDir string
// KeyStore optionally overrides where cryptographic keys come from. When
// nil (the default), authcore uses the disk store under KeysDir. Set it to
// source keys from a secret manager, environment, or KMS instead — see
// NewKeyStoreFromKeys and NewKeyStoreFromPEM. When set, KeysDir is ignored.
KeyStore KeyStore
}
Config holds the top-level configuration for an AuthCore instance. Zero values are replaced by safe defaults via DefaultConfig or applyDefaults.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a Config populated with safe, production-ready defaults.
cfg := authcore.DefaultConfig() cfg.EnableLogs = false // disable logs for tests auth, err := authcore.New(cfg)
Example ¶
package main
import (
"fmt"
"github.com/Glyndor/authcore"
)
func main() {
cfg := authcore.DefaultConfig()
fmt.Println(cfg.KeysDir)
}
Output: .authcore
type KeyStore ¶ added in v1.6.0
type KeyStore interface {
// Load returns the key material, or an error if it cannot be obtained or
// fails validation.
Load() (Keys, error)
}
KeyStore sources authcore's cryptographic key material (the Ed25519 signing pair and the HMAC refresh secret).
The default is disk: New generates and loads PEM files under Config.KeysDir. Set Config.KeyStore to override that — for example to source keys from a secret manager, environment variables, or KMS, which is the right fit for serverless or disk-averse deployments where a mounted volume is awkward.
Implementations are consulted once, at New time. The returned Keys must be stable for the lifetime of the AuthCore instance.
func NewKeyStoreFromKeys ¶ added in v1.6.0
func NewKeyStoreFromKeys(priv ed25519.PrivateKey, pub ed25519.PublicKey, refreshSecret []byte) (KeyStore, error)
NewKeyStoreFromKeys returns a KeyStore backed by in-memory Ed25519 material, touching no filesystem. Use it to inject keys obtained from a secret manager or KMS at startup.
It validates that pub is the public half of priv and that refreshSecret is 32 bytes. Assign the result to Config.KeyStore.
func NewKeyStoreFromPEM ¶ added in v1.6.0
NewKeyStoreFromPEM returns a KeyStore from PEM-encoded material: a PKCS#8 private key, a PKIX public key, and the raw 32-byte refresh secret. This is the convenient form when keys arrive as PEM strings from environment variables or a secret store.
Assign the result to Config.KeyStore.
type Keys ¶
type Keys interface {
// PrivateKey returns the Ed25519 private key used for signing tokens.
// The caller must not modify the returned slice.
PrivateKey() ed25519.PrivateKey
// PublicKey returns the Ed25519 public key used for signature verification.
// The caller must not modify the returned slice.
PublicKey() ed25519.PublicKey
// RefreshSecret returns the 32-byte HMAC-SHA256 key used to hash refresh
// tokens before they are stored in a database.
// The caller must not modify the returned slice.
RefreshSecret() []byte
// KeyID returns the stable identifier for the current signing key.
// It is derived from the public key and embedded in the "kid" JOSE header
// of every issued token so that verifiers can select the correct key when
// multiple keys are in circulation (e.g. during key rotation).
KeyID() string
}
Keys provides read-only access to authcore's managed cryptographic material.
The concrete implementation is *keymanager.KeyManager (internal). Sub-modules receive Keys through the Provider interface and must not cache or copy the raw key bytes — always call the accessor methods.
type Logger ¶
type Logger interface {
Debug(msg string, args ...any)
Info(msg string, args ...any)
Warn(msg string, args ...any)
Error(msg string, args ...any)
}
Logger is the logging interface used throughout authcore. Implement this interface to plug in any logging backend (slog, zap, zerolog, etc.).
type Module ¶
type Module interface {
// Name returns the unique, lowercase identifier of this module.
// It must be stable across releases because callers may use it as a key.
// Examples: "jwt", "apikey", "oauth"
Name() string
}
Module is the minimal contract every authcore authentication sub-module must implement. It acts as a marker interface today and will grow as shared lifecycle requirements (e.g. Close, HealthCheck) are identified.
Available implementations and their concrete constructors:
auth/jwt — JSON Web Token authentication (EdDSA / Ed25519)
jwt.New[T any](p authcore.Provider, cfg ...jwt.Config) (*jwt.JWT[T], error)
auth/password — Argon2id password hashing
password.New(p authcore.Provider, cfg ...password.Config) (*password.Password, error)
auth/email — email validation, normalization, DNS MX verification
email.New(p authcore.Provider) (*email.Email, error)
auth/username — username validation, normalization, reserved name blocklist
username.New(p authcore.Provider) (*username.Username, error)
auth/apikey — opaque API key generation, hashing, and verification
apikey.New(p authcore.Provider, cfg ...apikey.Config) (*apikey.APIKey, error)
auth/oauth — OpenID Connect client (login with Google / Microsoft / OIDC)
oauth.New(p authcore.Provider, cfg oauth.Config) (*oauth.Client, error)
Conventions shared by every module:
- The first argument is always an authcore.Provider (never a concrete *AuthCore).
- Where a module takes a Config, it is variadic-optional: omit it, or pass a zero-value Config, to apply safe production defaults via applyDefaults. The email and username modules need no Config. Construct any module and use it — none requires cleanup.
- Constructors return a pointer receiver; concrete types are safe for concurrent use across goroutines after construction completes.
type Provider ¶
type Provider interface {
// Config returns a copy of the active library configuration.
Config() Config
// Logger returns the active logger shared across the library.
// Modules must use this logger rather than creating their own so that
// all output flows through a single, user-configured sink.
Logger() Logger
// Keys returns the library's managed cryptographic material.
// Sub-modules must call this to obtain signing keys and the refresh secret.
Keys() Keys
}
Provider is the narrow interface that *AuthCore satisfies.
Sub-modules must accept a Provider rather than *AuthCore directly. This decouples each module from the concrete library type, which has two important consequences:
Testability — unit tests can inject a stub Provider without constructing a real AuthCore or touching the file system / network.
Stability — if AuthCore gains new methods in a future release, existing module code is unaffected because it only depends on the methods below.
Guaranteed implementation: *AuthCore.
Directories
¶
| Path | Synopsis |
|---|---|
|
auth
|
|
|
apikey
Package apikey issues and verifies opaque API keys for authcore.
|
Package apikey issues and verifies opaque API keys for authcore. |
|
email
Package email provides email address validation and normalization for authcore.
|
Package email provides email address validation and normalization for authcore. |
|
jwt
Package jwt provides JSON Web Token (JWT) authentication for authcore.
|
Package jwt provides JSON Web Token (JWT) authentication for authcore. |
|
oauth
Package oauth is an OpenID Connect (OIDC) client for authcore — "log in with Google / Microsoft / any OIDC provider".
|
Package oauth is an OpenID Connect (OIDC) client for authcore — "log in with Google / Microsoft / any OIDC provider". |
|
password
Package password provides Argon2id password hashing for authcore.
|
Package password provides Argon2id password hashing for authcore. |
|
username
Package username provides username validation and normalization for authcore.
|
Package username provides username validation and normalization for authcore. |
|
internal
|
|
|
clock
Package clock provides a time-source abstraction used across all authcore modules.
|
Package clock provides a time-source abstraction used across all authcore modules. |
|
keymanager
Package keymanager handles the creation, storage, and loading of authcore's cryptographic key material.
|
Package keymanager handles the creation, storage, and loading of authcore's cryptographic key material. |