GoodMem
ReferenceAPIgRPC API

Apikey

Apikey service API reference

Services

ApiKeyService Service

Service for managing API Keys in the GoodMem system.

Authentication: gRPC metadata authorization: Bearer <api-key>

Global errors: All RPCs may return DEADLINE_EXCEEDED, CANCELLED, UNAVAILABLE, RESOURCE_EXHAUSTED, INTERNAL.

Permissions model:

  • *_APIKEY_OWN: operate on caller-owned API keys
  • *_APIKEY_ANY: operate on any user's API keys (requires elevated role)

CreateApiKey

Creates a new API key for the authenticated user.

Type
Requestgoodmem.v1.CreateApiKeyRequest
Responsegoodmem.v1.CreateApiKeyResponse

Auth: gRPC metadata authorization: Bearer <api-key>

Permissions Required: CREATE_APIKEY_OWN or CREATE_APIKEY_ANY

Summary:

  • The raw API key is returned ONLY in this response; client MUST save it immediately
  • Once the response is processed, the raw key material is never accessible again
  • New keys start in ACTIVE status
  • ALREADY_EXISTS: if client-provided api_key_id is already in use

Side Effects:

  • Persists API key; generates cryptographically secure key material; sets audit fields

Error Codes:

  • UNAUTHENTICATED: missing/invalid auth
  • PERMISSION_DENIED: lacks CREATE_APIKEY_*
  • INVALID_ARGUMENT: expires_at in the past; labels exceed limits or contain invalid characters
  • ALREADY_EXISTS: client-provided api_key_id already exists
  • INTERNAL: unexpected server error

Idempotency: Non-idempotent; clients SHOULD NOT blindly retry on unknown failures.

Examples:

grpcurl -plaintext \
-H 'authorization: Bearer gm_xxx' \
-d '{
"labels": {"env": "dev", "service": "backend"}
}' \
localhost:8080 goodmem.v1.ApiKeyService/CreateApiKey

Note: bytes fields in JSON must be base64.

ListApiKeys

Lists API keys belonging to the authenticated user.

Type
Requestgoodmem.v1.ListApiKeysRequest
Responsegoodmem.v1.ListApiKeysResponse

Auth: gRPC metadata authorization: Bearer <api-key>

Permissions Required: LIST_APIKEY_OWN or LIST_APIKEY_ANY

Summary:

  • Returns metadata for all API keys owned by the caller
  • Raw key material and key hashes are never included in responses
  • With LIST_APIKEY_ANY, returns all keys in the system

Side Effects: None

Error Codes:

  • UNAUTHENTICATED: missing/invalid auth
  • PERMISSION_DENIED: lacks LIST_APIKEY_*
  • INTERNAL: unexpected server error

Idempotency: Read-only; safe to retry; results may change over time.

Examples:

grpcurl -plaintext \
-H 'authorization: Bearer gm_xxx' \
-d '{}' \
localhost:8080 goodmem.v1.ApiKeyService/ListApiKeys

UpdateApiKey

Updates mutable properties of an API key.

Type
Requestgoodmem.v1.UpdateApiKeyRequest
Responsegoodmem.v1.ApiKey

Auth: gRPC metadata authorization: Bearer <api-key>

Permissions Required: UPDATE_APIKEY_OWN or UPDATE_APIKEY_ANY

Summary:

  • Mutable fields: status, labels
  • Immutable fields: api_key_id, user_id, key material, created_at, created_by_id
  • Label updates support replace (clear all, set new) or merge (upsert) strategies

Side Effects:

  • Persists changes; updates updated_at and updated_by_id

Error Codes:

  • UNAUTHENTICATED: missing/invalid auth
  • PERMISSION_DENIED: lacks UPDATE_APIKEY_*
  • INVALID_ARGUMENT: invalid api_key_id format; both label strategies set; STATUS_UNSPECIFIED provided; no updatable fields
  • NOT_FOUND: API key does not exist
  • INTERNAL: unexpected server error

Idempotency: Idempotent with identical input; safe to retry.

Examples:

grpcurl -plaintext \
-H 'authorization: Bearer gm_xxx' \
-d '{
"api_key_id": "BASE64_UUID_BYTES_HERE",
"status": "INACTIVE"
}' \
localhost:8080 goodmem.v1.ApiKeyService/UpdateApiKey

Note: bytes fields in JSON must be base64.

DeleteApiKey

Permanently deletes an API key.

Type
Requestgoodmem.v1.DeleteApiKeyRequest
Responsegoogle.protobuf.Empty

Auth: gRPC metadata authorization: Bearer <api-key>

Permissions Required: DELETE_APIKEY_OWN or DELETE_APIKEY_ANY

Summary:

  • This operation is irreversible and immediately invalidates the key
  • Use UpdateApiKey with status=INACTIVE for reversible deactivation

Side Effects:

  • Permanently removes the API key record; invalidates key for all future authentication

Error Codes:

  • UNAUTHENTICATED: missing/invalid auth
  • PERMISSION_DENIED: lacks DELETE_APIKEY_*
  • INVALID_ARGUMENT: invalid api_key_id format
  • NOT_FOUND: API key does not exist
  • INTERNAL: unexpected server error

Idempotency: Safe to retry; may return NOT_FOUND if already deleted or never existed.

Examples:

grpcurl -plaintext \
-H 'authorization: Bearer gm_xxx' \
-d '{ "api_key_id": "BASE64_UUID_BYTES_HERE" }' \
localhost:8080 goodmem.v1.ApiKeyService/DeleteApiKey

Note: bytes fields in JSON must be base64.

Messages

ApiKey

Represents an API key for authenticating requests to the GoodMem service.

API keys are scoped to individual users and provide secure, token-based authentication for both gRPC and REST API endpoints. Each key includes metadata for identification and management, while the actual key material is securely hashed and stored separately.

Security:

  • key_hash and raw key material are never included in API responses.
  • The raw API key is only returned once during creation via CreateApiKeyResponse.
  • Key material is cryptographically hashed using secure algorithms.
  • Authentication validates both status=ACTIVE and expires_at (if set).

Lifecycle:

  • Keys can be disabled by setting status to INACTIVE (reversible).
  • Keys can be permanently deleted using DeleteApiKey (irreversible).
  • Keys automatically become invalid after expires_at (if set).
  • Active keys with no expiration remain valid indefinitely.

Immutability:

  • api_key_id is the immutable primary identifier.
  • user_id is set at creation and cannot be modified.

Notes:

  • All timestamps are UTC (google.protobuf.Timestamp).

See also: goodmem.v1.ApiKeyStatus

FieldTypeDescription
api_key_idbytesOUTPUT_ONLY UUID (16 bytes); immutable primary identifier
user_idbytesOUTPUT_ONLY UUID (16 bytes); owner of this key; immutable after creation
key_prefixstringOUTPUT_ONLY display prefix (format: "gm_" + 6 chars, e.g., "gm_1234ab")
statusgoodmem.v1.ApiKeyStatusREQUIRED; current lifecycle status. See: goodmem.v1.ApiKeyStatus
labelsgoodmem.v1.ApiKey.LabelsEntryOPTIONAL; ≤20 entries; keys/values ≤255 chars; keys [a-z0-9._-], case-sensitive
expires_atgoogle.protobuf.TimestampOPTIONAL expiration time (UTC); if set, key becomes invalid after this time
last_used_atgoogle.protobuf.TimestampOUTPUT_ONLY; may be sampled/delayed; not updated on every request
created_atgoogle.protobuf.TimestampOUTPUT_ONLY creation timestamp (UTC). See: `google.protobuf.Timestamp`
updated_atgoogle.protobuf.TimestampOUTPUT_ONLY last modification timestamp (UTC). See: `google.protobuf.Timestamp`
created_by_idbytesOUTPUT_ONLY creator user UUID (16 bytes); typically the key owner
updated_by_idbytesOUTPUT_ONLY last modifier user UUID (16 bytes); derived from auth context on update

ApiKey.LabelsEntry

FieldTypeDescription
keystring
valuestring

CreateApiKeyRequest

FieldTypeDescription
api_key_idbytesOptional client-provided UUID (16 bytes); server generates if omitted; returns ALREADY_EXISTS if ID exists
labels...reateApiKeyRequest.LabelsEntryOptional labels (≤20 entries; keys/values ≤255 chars; keys [a-z0-9._-], case-sensitive)
expires_atgoogle.protobuf.TimestampOptional expiration (UTC); `INVALID_ARGUMENT` if in the past

CreateApiKeyRequest.LabelsEntry

FieldTypeDescription
keystring
valuestring

CreateApiKeyResponse

Response for CreateApiKey containing the one-time raw key.

Security:

  • raw_api_key is returned ONLY in this response
  • Client MUST save the raw key immediately; it cannot be retrieved again
FieldTypeDescription
api_key_metadatagoodmem.v1.ApiKeyThe created API key metadata (excludes raw key material and hash)
raw_api_keystringThe actual generated API key; client MUST save this immediately

ListApiKeysRequest

Future: user_id filter for admins with LIST_APIKEY_ANY permission

ListApiKeysResponse

FieldTypeDescription
keysgoodmem.v1.ApiKeyList of API keys (metadata only; raw key material never included)

UpdateApiKeyRequest

FieldTypeDescription
api_key_idbytesRequired: ID of the key to update (16 bytes UUID)
replace_labelsgoodmem.v1.StringMapReplace all existing labels with this set. Empty StringMap clears all labels.
See: goodmem.v1.StringMap
merge_labelsgoodmem.v1.StringMapMerge with existing labels: upserts with overwrite. Labels not mentioned are preserved.
See: goodmem.v1.StringMap
statusgoodmem.v1.ApiKeyStatusOptional fields to update (if omitted → unchanged)
Update status; `STATUS_UNSPECIFIED` → `INVALID_ARGUMENT`. See: goodmem.v1.ApiKeyStatus

DeleteApiKeyRequest

FieldTypeDescription
api_key_idbytesRequired: ID of the key to delete (16 bytes UUID)

Enums

ApiKeyStatus

API key status for lifecycle management.

  • STATUS_UNSPECIFIED = 0: Invalid status; never used in practice
  • ACTIVE = 1: Key is valid and can be used for authentication
  • INACTIVE = 2: Key is disabled and cannot be used for authentication (reversible revocation)
NameValueDescription
STATUS_UNSPECIFIED0Invalid status; `INVALID_ARGUMENT` on writes
ACTIVE1Key is valid and can be used for authentication
INACTIVE2Key is disabled; authentication attempts are rejected