Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go/apps/api/routes/v2_keys_verify_key/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func (h *Handler) Handle(ctx context.Context, s *zen.Session) error {
AutoApply: result.AutoApply,
Duration: result.Duration.Milliseconds(),
Exceeded: !result.Response.Success,
Id: result.Name,
Id: result.ID,
Limit: result.Limit,
Name: result.Name,
Remaining: result.Response.Remaining,
Expand Down
1 change: 0 additions & 1 deletion go/apps/api/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (

// nolint:gocognit
func Run(ctx context.Context, cfg Config) error {

err := cfg.Validate()
if err != nil {
return fmt.Errorf("bad config: %w", err)
Expand Down
2 changes: 2 additions & 0 deletions go/internal/services/keys/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
type KeyService interface {
// Get retrieves a key and returns a KeyVerifier for validation
Get(ctx context.Context, sess *zen.Session, hash string) (*KeyVerifier, func(), error)

// GetRootKey retrieves and validates a root key from the session
GetRootKey(ctx context.Context, sess *zen.Session) (*KeyVerifier, func(), error)

// CreateKey generates a new secure API key
CreateKey(ctx context.Context, req CreateKeyRequest) (CreateKeyResponse, error)
}
Expand Down
6 changes: 5 additions & 1 deletion go/internal/services/keys/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ func (k *KeyVerifier) withRateLimits(ctx context.Context, specifiedLimits []open
}

ratelimitsToCheck[name] = RatelimitConfigAndResult{
ID: rl.ID,
Cost: 1,
Name: rl.Name,
Duration: time.Duration(rl.Duration) * time.Millisecond,
Expand All @@ -154,15 +155,17 @@ func (k *KeyVerifier) withRateLimits(ctx context.Context, specifiedLimits []open
}

for _, rl := range specifiedLimits {
// Custom limits are always applied on a key level
if rl.Limit != nil && rl.Duration != nil {
ratelimitsToCheck[rl.Name] = RatelimitConfigAndResult{
Cost: int64(ptr.SafeDeref(rl.Cost, 1)),
Name: rl.Name,
Duration: time.Duration(*rl.Duration) * time.Millisecond,
Limit: int64(*rl.Limit),
AutoApply: false,
Identifier: k.Key.ID, // Specified limits use key ID
Identifier: k.Key.ID,
Response: nil,
ID: "", // Doesn't exist and is custom so no ID
}

continue
Expand Down Expand Up @@ -197,6 +200,7 @@ func (k *KeyVerifier) withRateLimits(ctx context.Context, specifiedLimits []open
AutoApply: dbRl.AutoApply == 1,
Identifier: identifier,
Response: nil,
ID: dbRl.ID,
}
}

Expand Down
42 changes: 25 additions & 17 deletions go/internal/services/keys/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keys

import (
"context"
"os"
"time"

"github.com/unkeyed/unkey/go/internal/services/ratelimit"
Expand All @@ -17,6 +18,7 @@ import (

// RatelimitConfigAndResult holds both the configuration and result for a rate limit
type RatelimitConfigAndResult struct {
ID string
Cost int64
Name string
Duration time.Duration
Expand All @@ -29,22 +31,28 @@ type RatelimitConfigAndResult struct {
// KeyVerifier represents a key that has been loaded from the database and is ready for verification.
// It contains all the necessary information and services to perform various validation checks.
type KeyVerifier struct {
Key db.FindKeyForVerificationRow // The key data from the database
ratelimitConfigs map[string]db.KeyFindForVerificationRatelimit // Rate limits configured for this key (name -> config)
Roles []string // RBAC roles assigned to this key
Permissions []string // RBAC permissions assigned to this key
Status KeyStatus // The current validation status
AuthorizedWorkspaceID string // The workspace ID this key is authorized for
RatelimitResults map[string]RatelimitConfigAndResult // Combined config and results for rate limits (name -> config+result)
isRootKey bool // Whether this is a root key (special handling)
session *zen.Session // The current request session
rateLimiter ratelimit.Service // Rate limiting service
usageLimiter usagelimiter.Service // Usage limiting service
rBAC *rbac.RBAC // Role-based access control service
clickhouse clickhouse.ClickHouse // Clickhouse for telemetry
logger logging.Logger // Logger for verification operations
message string // Internal message for validation failures
tags []string // Tags associated with the key
Key db.FindKeyForVerificationRow // The key data from the database
Roles []string // RBAC roles assigned to this key
Permissions []string // RBAC permissions assigned to this key
Status KeyStatus // The current validation status
AuthorizedWorkspaceID string // The workspace ID this key is authorized for

ratelimitConfigs map[string]db.KeyFindForVerificationRatelimit // Rate limits configured for this key (name -> config)
RatelimitResults map[string]RatelimitConfigAndResult // Combined config and results for rate limits (name -> config+result)

isRootKey bool // Whether this is a root key (special handling)

message string // Internal message for validation failures
tags []string // Tags associated with this verification

session *zen.Session // The current request session

// Services
rateLimiter ratelimit.Service // Rate limiting service
usageLimiter usagelimiter.Service // Usage limiting service
rBAC *rbac.RBAC // Role-based access control service
clickhouse clickhouse.ClickHouse // Clickhouse for telemetry
logger logging.Logger // Logger for verification operations
}

// GetRatelimitConfigs returns the rate limit configurations
Expand Down Expand Up @@ -117,12 +125,12 @@ func (k *KeyVerifier) log() {
RequestID: k.session.RequestID(),
WorkspaceID: k.Key.WorkspaceID,
Time: time.Now().UnixMilli(),
Region: "",
Outcome: string(k.Status),
KeySpaceID: k.Key.KeyAuthID,
KeyID: k.Key.ID,
IdentityID: k.Key.IdentityID.String,
Tags: k.tags,
Region: os.Getenv("UNKEY_REGION"),
Comment thread
Flo4604 marked this conversation as resolved.
Outdated
})

keyType := "key"
Expand Down