@@ -42,6 +42,7 @@ type CreateAPIKeyRequest struct {
4242 Description string
4343 IdentityID string
4444 CredentialPolicyID string // Optional — if empty, the tenant's default policy is assigned.
45+ Product string
4546 Scopes []string
4647 Environment string
4748 ExpiresInDays * int
@@ -63,9 +64,20 @@ type CreateAPIKeyResponse struct {
6364
6465// CreateKey generates a new API key, hashes it, stores the hash, and returns the full key once.
6566// Every key is linked to an identity and assigned a credential policy.
66- // If IdentityID is empty, no identity link is set.
67+ // If IdentityID is empty and Product is set, a service identity is auto-provisioned
68+ // (or reused if one already exists for this account+project+product).
6769// If CredentialPolicyID is empty, the tenant's default policy is auto-created and assigned.
6870func (s * APIKeyService ) CreateKey (ctx context.Context , req CreateAPIKeyRequest ) (* CreateAPIKeyResponse , error ) {
71+ // Ensure every key has an identity link.
72+ // When no identity is provided, auto-provision a service identity for the product.
73+ if req .IdentityID == "" && req .Product != "" {
74+ identity , err := s .identitySvc .EnsureServiceIdentity (ctx , req .AccountID , req .ProjectID , req .Product , req .CreatedBy )
75+ if err != nil {
76+ return nil , fmt .Errorf ("failed to ensure service identity for product %s: %w" , req .Product , err )
77+ }
78+ req .IdentityID = identity .ID
79+ }
80+
6981 // Ensure the key has a credential policy.
7082 policyID := req .CredentialPolicyID
7183 if policyID == "" {
@@ -114,6 +126,7 @@ func (s *APIKeyService) CreateKey(ctx context.Context, req CreateAPIKeyRequest)
114126 IdentityID : req .IdentityID ,
115127 CreatedBy : req .CreatedBy ,
116128 CredentialPolicyID : policyID ,
129+ Product : req .Product ,
117130 Scopes : scopes ,
118131 Environment : env ,
119132 ExpiresAt : expiresAt ,
@@ -145,7 +158,7 @@ func (s *APIKeyService) CreateKey(ctx context.Context, req CreateAPIKeyRequest)
145158}
146159
147160// ListKeys returns paginated API keys for an account/project.
148- func (s * APIKeyService ) ListKeys (ctx context.Context , accountID , projectID , applicationID , product string , page , limit int ) ([]* domain.APIKey , int , error ) {
161+ func (s * APIKeyService ) ListKeys (ctx context.Context , accountID , projectID , applicationID , product , label string , page , limit int ) ([]* domain.APIKey , int , error ) {
149162 if page < 1 {
150163 page = 1
151164 }
@@ -154,7 +167,7 @@ func (s *APIKeyService) ListKeys(ctx context.Context, accountID, projectID, appl
154167 }
155168 offset := (page - 1 ) * limit
156169
157- return s .repo .ListByAccountProject (ctx , accountID , projectID , applicationID , product , limit , offset )
170+ return s .repo .ListByAccountProject (ctx , accountID , projectID , applicationID , product , label , limit , offset )
158171}
159172
160173// GetKey returns an API key by ID.
0 commit comments