mintcore

package module
v0.0.0-...-30e3e72 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package mintcore provides shared code for the fullsend token mint implementations (GCP Cloud Function and local dev mint).

Index

Constants

This section is empty.

Variables

View Source
var (
	Version string
	Commit  string
)

Version and Commit are stamped into the Cloud Function source at deployment time by the provisioner. In development (local dev, tests) they default to empty strings.

View Source
var GitHubOrgPattern = regexp.MustCompile(`^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$`)

GitHubOrgPattern validates GitHub org/user names: alphanumeric or single hyphens, cannot start or end with a hyphen, max 39 characters.

View Source
var RepoNamePattern = regexp.MustCompile(`^[a-zA-Z0-9_.][a-zA-Z0-9._-]{0,99}$`)

RepoNamePattern validates individual repo names (no org prefix). GitHub allows repos starting with dot (e.g., .fullsend, .github).

View Source
var RolePattern = regexp.MustCompile(`^[a-z][a-z0-9_-]*$`)

RolePattern restricts role to safe lowercase identifiers.

Functions

func BuildRepoProviderID

func BuildRepoProviderID(owner, repo string) string

BuildRepoProviderID generates a GCP WIF provider ID scoped to a single repo. GCP requires 4-32 chars, [a-z][a-z0-9-]*, no trailing hyphen.

func CallerAllowed

func CallerAllowed(allowlist []string, repository, repositoryOwner string) bool

CallerAllowed reports whether repository/repositoryOwner matches an allowlist entry. Entries with a slash match the repository claim exactly; bare org names match repository_owner.

func FindInstallation

func FindInstallation(ctx context.Context, httpClient HTTPDoer, githubBaseURL, jwt, org, repo string) (int64, error)

FindInstallation looks up a GitHub App's installation ID for a repo. The returned installation's account is verified against the expected org to prevent cross-org token leakage.

func FindOrgInstallation

func FindOrgInstallation(ctx context.Context, httpClient HTTPDoer, githubBaseURL, jwt, org string) (int64, error)

FindOrgInstallation looks up a GitHub App's installation ID for an organization.

func ForeignVariableName

func ForeignVariableName(role string) string

ForeignVariableName returns the org variable name for cross-org allowlist policy.

func GenerateAppJWT

func GenerateAppJWT(appID string, pemData []byte) (string, error)

GenerateAppJWT creates a signed RS256 JWT for GitHub App authentication.

func GetOrgVariable

func GetOrgVariable(ctx context.Context, httpClient HTTPDoer, githubBaseURL, installationToken, org, name string) (value string, exists bool, err error)

GetOrgVariable reads an org-level Actions variable using an installation token.

func HasRole

func HasRole(role string) bool

HasRole reports whether the given role has a permissions entry, checking canonical roles first (avoids atomic load on the hot path), then custom roles.

func IsPublicMint

func IsPublicMint(allowedOrgs []string) bool

IsPublicMint reports whether ALLOWED_ORGS contains *, enabling public mint mode.

func ParseAllowedOrgs

func ParseAllowedOrgs(allowedOrgs string) []string

ParseAllowedOrgs splits a comma-separated ALLOWED_ORGS value into trimmed entries.

func ParseForeignAllowlist

func ParseForeignAllowlist(value string) []string

ParseForeignAllowlist splits a comma-separated FOREIGN variable value into entries.

func PemSecretRole

func PemSecretRole(role string) string

PemSecretRole returns the PEM secret role key for a mint request role. The fix stage uses the coder PEM.

func ReadForeignAllowlist

func ReadForeignAllowlist(ctx context.Context, httpClient HTTPDoer, githubBaseURL, jwt string, installationID int64, targetOrg, role string) ([]string, error)

ReadForeignAllowlist reads FULLSEND_FOREIGN_<role>_REPOS from the target org.

func RegisterCustomRolePermissions

func RegisterCustomRolePermissions(perms map[string]map[string]string) error

RegisterCustomRolePermissions adds user-defined role permissions that are checked alongside the canonical built-in permissions. Pass nil to clear. Returns an error if any custom role name collides with a built-in role. Used by cmd/mint (standalone mint) only; the GCF mint uses canonical roles.

func RoleOnlyAppIDs

func RoleOnlyAppIDs(ids map[string]string) map[string]string

RoleOnlyAppIDs extracts role-keyed entries from ROLE_APP_IDS, ignoring legacy org/role keys left over during migration.

func RolePermissions

func RolePermissions() map[string]map[string]string

RolePermissions returns a deep copy of the combined canonical and custom role-to-permissions map. Custom roles are included alongside canonical ones.

func RolePermissionsFor

func RolePermissionsFor(role string) map[string]string

RolePermissionsFor returns the permissions for a specific role, or nil if the role is not defined. Canonical roles are checked first (avoids atomic load on the hot path), then custom roles. Name collisions are rejected at registration time so lookups are unambiguous. The returned map is a copy.

func ValidateOrgAllowed

func ValidateOrgAllowed(org string, allowedOrgs []string) error

ValidateOrgAllowed checks that org is in the allowed list (case-insensitive). When allowedOrgs contains *, any non-empty org is accepted (public mint mode).

func ValidateOrgName

func ValidateOrgName(org string) error

ValidateOrgName checks that an org name matches GitHubOrgPattern and does not contain double-hyphens (which would be ambiguous in secret names).

func ValidateRoleName

func ValidateRoleName(role string) error

ValidateRoleName checks that a role name matches RolePattern and does not contain double-hyphens.

func ValidateWorkflowRef

func ValidateWorkflowRef(ref, repository string, allowedOrgs []string, perRepoWIFRepos map[string]bool, allowedWorkflowFiles []string) error

ValidateWorkflowRef checks that a job_workflow_ref claim references an allowed workflow. In public mint mode (allowedOrgs contains *), only upstream fullsend-ai/fullsend workflows are accepted and the basename allowlist is skipped. In tight mode, the ref may belong to the token owner's .fullsend config repo, the upstream fullsend-ai/fullsend repo, or a registered per-repo repo, and the workflow file must be in the allowed list. The repository parameter is the token's repository claim and is used to cross-check per-repo matches.

Types

type Audience

type Audience []string

Audience handles the OIDC aud claim which can be a string or array of strings.

func (Audience) Contains

func (a Audience) Contains(aud string) bool

Contains reports whether aud is in the audience list.

func (*Audience) UnmarshalJSON

func (a *Audience) UnmarshalJSON(data []byte) error

UnmarshalJSON handles both string and array-of-strings forms.

type Claims

type Claims struct {
	Issuer          string   `json:"iss"`
	Audience        Audience `json:"aud"`
	IssuedAt        int64    `json:"iat"`
	Expiry          int64    `json:"exp"`
	Repository      string   `json:"repository"`
	RepositoryOwner string   `json:"repository_owner"`
	JobWorkflowRef  string   `json:"job_workflow_ref"`
}

Claims holds the subset of GitHub Actions OIDC JWT claims validated by the mint.

type FilesystemPEMAccessor

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

FilesystemPEMAccessor reads agent PEMs from a local directory. PEM files are named {role}.pem (e.g. coder.pem, triage.pem).

func NewFilesystemPEMAccessor

func NewFilesystemPEMAccessor(pemDir string) (*FilesystemPEMAccessor, error)

NewFilesystemPEMAccessor creates a PEM accessor that reads from a local directory. The directory must exist at construction time.

func (*FilesystemPEMAccessor) AccessPEM

func (f *FilesystemPEMAccessor) AccessPEM(_ context.Context, role string) ([]byte, error)

type GCPSecretPEMAccessor

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

GCPSecretPEMAccessor reads agent PEMs from GCP Secret Manager via REST API, authenticating with the GCE metadata server token. Secret naming convention: projects/{num}/secrets/fullsend-{role}-app-pem/versions/latest

func NewGCPSecretPEMAccessor

func NewGCPSecretPEMAccessor(httpClient HTTPDoer, gcpProjectNum string) *GCPSecretPEMAccessor

NewGCPSecretPEMAccessor creates a PEM accessor that reads from GCP Secret Manager.

func (*GCPSecretPEMAccessor) AccessPEM

func (s *GCPSecretPEMAccessor) AccessPEM(ctx context.Context, role string) ([]byte, error)

type GrantedScope

type GrantedScope struct {
	Repos          []string
	Permissions    map[string]string
	RepoSelection  string
	AppID          string
	InstallationID int64
}

GrantedScope holds the actual scope GitHub granted for the installation token.

func CreateInstallationToken

func CreateInstallationToken(ctx context.Context, httpClient HTTPDoer, githubBaseURL, jwt string, installationID int64, role string, repos []string) (string, string, *GrantedScope, error)

CreateInstallationToken exchanges a JWT for an installation access token, scoped to the given repos and role-specific permissions.

type HTTPDoer

type HTTPDoer interface {
	Do(req *http.Request) (*http.Response, error)
}

HTTPDoer abstracts http.Client for testability.

type Handler

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

Handler holds dependencies for the token mint HTTP server.

func NewHandler

func NewHandler(pemAccessor PEMAccessor, oidcVerifier OIDCVerifier) (*Handler, error)

NewHandler creates a Handler with the given dependencies. Environment variables for handler-level config (ROLE_APP_IDS, ALLOWED_ROLES) are read once at construction time. The OIDCVerifier is injected by the caller so different verification strategies can be used (STSVerifier for the Cloud Function, JWKSVerifier for devmint). Org validation is the OIDCVerifier's responsibility.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles incoming token mint requests.

type JWKSVerifier

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

JWKSVerifier validates GitHub Actions OIDC JWTs by fetching JWKS from the issuer's discovery endpoint and verifying RS256 signatures directly.

func NewJWKSVerifier

func NewJWKSVerifier(opts JWKSVerifierConfig) *JWKSVerifier

NewJWKSVerifier creates a verifier that validates tokens from issuerURL against the given audience. If httpClient is nil, http.DefaultClient is used.

func (*JWKSVerifier) Verify

func (v *JWKSVerifier) Verify(ctx context.Context, rawToken string) (*Claims, error)

Verify validates a raw JWT string and returns the parsed claims.

type JWKSVerifierConfig

type JWKSVerifierConfig struct {
	IssuerURL            string
	Audience             string
	HTTPClient           HTTPDoer
	AllowedOrgs          []string
	AllowedWorkflowFiles []string
	PerRepoWIFRepos      map[string]bool
}

JWKSVerifierConfig configures a new JWKSVerifier.

type OIDCVerifier

type OIDCVerifier interface {
	Verify(ctx context.Context, rawToken string) (*Claims, error)
}

OIDCVerifier validates OIDC tokens and returns parsed claims. Implementations include JWKSVerifier (direct JWKS validation) and STSVerifier (GCP Workload Identity Federation via STS exchange).

type PEMAccessor

type PEMAccessor interface {
	AccessPEM(ctx context.Context, role string) ([]byte, error)
}

PEMAccessor retrieves agent PEM keys by role. Implementations encapsulate the storage backend (GCP Secret Manager, local filesystem, etc.).

type STSVerifier

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

STSVerifier validates OIDC tokens by exchanging them with GCP STS (Workload Identity Federation). It performs lightweight JWT pre-validation before the STS exchange.

func NewSTSVerifier

func NewSTSVerifier(opts STSVerifierConfig) *STSVerifier

NewSTSVerifier creates a verifier that validates tokens via GCP STS exchange.

func (*STSVerifier) Verify

func (v *STSVerifier) Verify(ctx context.Context, rawToken string) (*Claims, error)

Verify pre-validates the JWT claims, then exchanges the token with GCP STS.

type STSVerifierConfig

type STSVerifierConfig struct {
	HTTPClient         HTTPDoer
	STSURL             string
	GCPProjectNum      string
	WIFPoolName        string
	DefaultWIFProvider string
	AllowedOrgs        []string
	AllowedWorkflows   []string
	PerRepoWIFRepos    map[string]bool
	OIDCAudience       string
}

STSVerifierConfig configures a new STSVerifier.

Jump to

Keyboard shortcuts

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