GoodMemGoodMem
ReferenceAPIgRPC API

Apikey

gRPC ApiKeyService reference for CreateApiKey, GetApiKey, ListApiKeys, UpdateApiKey and other RPCs, with request messages, response types, and service documentation.

Services

ApiKeyService Service

Service for managing API Keys in the GoodMem system.

Authentication: gRPC metadata x-api-key: <api-key>

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

Authorization model:

  • Create, update, and delete RPCs evaluate a typed authorization operation against the target API key and its administrative owner.
  • Listing first requires LIST_API_KEY on the singleton instance, then returns only credentials passing READ_API_KEY under the authenticated principal's effective authorization policy.

CreateApiKey

Creates a new API key for an active principal.

Type
Requestgoodmem.v1.CreateApiKeyRequest
Responsegoodmem.v1.CreateApiKeyResponse

Auth: gRPC metadata x-api-key: <api-key>

Authorization Required: CREATE_API_KEY on the proposed credential, evaluated using its proposed administrative owner.

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
  • Omitted subject and mode preserve the self-issued human inheriting-key behavior
  • SERVICE subjects require SCOPED plus a nonempty immutable ceiling
  • Every ceiling descriptor must be conservatively covered by both the subject's live authority and the issuing credential's effective authority
  • A scoped issuing credential may issue only another scoped credential; it cannot mint an inheriting credential that escapes its immutable ceiling
  • New keys start in ACTIVE status unless their validity window says otherwise
  • 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/subject authority, exceeds the issuing credential's effective authority, or a scoped credential attempts to issue an inheriting credential
  • INVALID_ARGUMENT: malformed mode, ceiling, validity window, or labels
  • NOT_FOUND: requested subject or assigned ceiling resource does not exist
  • FAILED_PRECONDITION: deleted subject or unsupported subject/mode combination
  • 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 'x-api-key: gm_xxx' \
-d '{
"labels": {"env": "dev", "service": "backend"}
}' \
localhost:8080 goodmem.v1.ApiKeyService/CreateApiKey

Note: bytes fields in JSON must be base64.

GetApiKey

Retrieves one API key by UUID with its complete immutable ceiling.

Type
Requestgoodmem.v1.GetApiKeyRequest
Responsegoodmem.v1.GetApiKeyResponse

Auth: gRPC metadata x-api-key: <api-key>

Authorization Required: READ_API_KEY on the existing credential, evaluated under the caller's live authority and any scoped-key ceiling.

Response: Complete non-secret metadata with ceiling_omitted=false. Raw and hashed key material are never returned.

Side Effects: None.

Error Codes:

  • UNAUTHENTICATED: Missing or invalid authentication.
  • INVALID_ARGUMENT: api_key_id is not one UUID.
  • NOT_FOUND: The credential does not exist. Existence is resolved before authorization.
  • PERMISSION_DENIED: Caller lacks effective READ_API_KEY on the existing credential.
  • INTERNAL: Unexpected authorization or database failure.

Idempotency: Read-only and safe to retry.

ListApiKeys

Lists API keys discoverable to the authenticated principal.

Type
Requestgoodmem.v1.ListApiKeysRequest
Responsegoodmem.v1.ListApiKeysResponse

Auth: gRPC metadata x-api-key: <api-key>

Authorization: Requires LIST_API_KEY on the singleton instance. Each returned row must independently pass READ_API_KEY on that credential. Both gates use the caller's live authority intersected with any scoped authenticating-key ceiling.

Summary:

  • Returns one page of metadata for API keys discoverable to the caller
  • Results use stable API-key UUID order
  • FULL is the default view and includes complete ceilings; its page size defaults to 10 and may not exceed 20. BASIC omits ceilings, defaults to 50, and may not exceed 1,000.
  • Subject, owner, and lifecycle filters are applied in PostgreSQL after authorization and never broaden result visibility.
  • Lifecycle is evaluated at current server time independently for each page. Credentials can cross lifecycle boundaries between page requests; clients must tolerate the resulting change in filter membership.
  • next_token is opaque and binds every stable filter, the resolved view, and the complete authentication context. It never accepts a caller-controlled lifecycle evaluation instant.
  • Raw key material and key hashes are never included in responses

Side Effects: None

Error Codes:

  • UNAUTHENTICATED: missing/invalid auth
  • INVALID_ARGUMENT: malformed UUID filter, unspecified/unknown lifecycle or view, invalid page size for the resolved view, or mismatched/malformed continuation token
  • PERMISSION_DENIED: caller lacks effective LIST_API_KEY on the singleton instance
  • INTERNAL: unexpected server error

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

Examples:

grpcurl -plaintext \
-H 'x-api-key: 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 x-api-key: <api-key>

Permissions Required:

  • Label changes require UPDATE_API_KEY
  • Setting status=INACTIVE requires DELETE_API_KEY
  • A combined label-and-deactivation request requires both operations

Summary:

  • Mutable fields: status, labels
  • Immutable fields: api_key_id, subject_principal_id, key material, created_at, and created_by_id
  • Label updates support replace (clear all, set new) or merge (upsert) strategies
  • Revocation is one-way; status=ACTIVE cannot reactivate an inactive key

Side Effects:

  • Persists changes; updates updated_at and updated_by_id

Error Codes:

  • UNAUTHENTICATED: missing/invalid auth
  • PERMISSION_DENIED: lacks an operation represented by the requested fields
  • INVALID_ARGUMENT: invalid api_key_id format; both label strategies set; STATUS_UNSPECIFIED provided; no updatable fields
  • FAILED_PRECONDITION: attempts to reactivate a revoked key
  • NOT_FOUND: API key does not exist
  • INTERNAL: unexpected server error

Idempotency: Idempotent with identical input; safe to retry.

Examples:

grpcurl -plaintext \
-H 'x-api-key: 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 revokes an API key.

Type
Requestgoodmem.v1.DeleteApiKeyRequest
Responsegoogle.protobuf.Empty

Auth: gRPC metadata x-api-key: <api-key>

Permissions Required: DELETE_API_KEY

Summary:

  • This operation is irreversible and immediately invalidates the key
  • The durable credential and audit history remain stored
  • UpdateApiKey with status=INACTIVE performs the same protected lifecycle transition

Side Effects:

  • Records permanent revocation time and actor; invalidates future authentication

Error Codes:

  • UNAUTHENTICATED: missing/invalid auth
  • PERMISSION_DENIED: lacks DELETE_API_KEY
  • 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 'x-api-key: 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 authenticate durable HUMAN or SERVICE principals and provide secure, token-based authentication for both gRPC and REST API endpoints. Each key separates its authenticated subject from its administrative owner and immutable issuance authority.

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 valid_from, expires_at, and permanent revocation state.

Lifecycle:

  • Setting status to INACTIVE permanently revokes a key.
  • DeleteApiKey performs the same permanent revocation while retaining durable audit metadata.
  • 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.
  • Subject, authority mode, validity window, and ceiling are fixed at issuance and cannot be modified.

Notes:

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

See also: goodmem.v1.ApiKeyStatus

FieldTypeDescription
api_key_idbytesOUTPUT_ONLY; immutable primary UUID (16 bytes).
key_prefixstringOUTPUT_ONLY; display prefix (format: "gm_" + 6 chars, e.g., "gm_1234ab").
statusgoodmem.v1.ApiKeyStatusOUTPUT_ONLY; compatibility usability status. ACTIVE means currently usable; INACTIVE combines
not-yet-valid, expired, and revoked credentials. See lifecycle_state for the precise state.
labelsgoodmem.v1.ApiKey.LabelsEntryOUTPUT_ONLY; at most 20 labels; keys/values at most 255 characters; keys use [a-z0-9._-].
expires_atgoogle.protobuf.TimestampOUTPUT_ONLY; exclusive expiration time (UTC), when one is configured.
last_used_atgoogle.protobuf.TimestampOUTPUT_ONLY; sampled or delayed latest-use time; not updated on every request.
subject_principal_idbytesOUTPUT_ONLY; UUID (16 bytes) of the principal authenticated by this key.
owner_principal_idbytesOUTPUT_ONLY; UUID (16 bytes) of the current administrative owner.
authority_modegoodmem.v1.ApiKeyAuthorityModeOUTPUT_ONLY; immutable authority-derivation mode.
valid_fromgoogle.protobuf.TimestampOUTPUT_ONLY; inclusive lower validity bound.
revoked_atgoogle.protobuf.TimestampOUTPUT_ONLY; permanent revocation time, when revoked.
revoked_by_idbytesOUTPUT_ONLY; exact audit actor UUID, when revoked.
ceilinggoodmem.v1.AccessPolicyRuleOUTPUT_ONLY; immutable ceiling. When ceiling_omitted is false, this is nonempty exactly for
SCOPED keys. A BASIC list projection intentionally leaves it empty and sets ceiling_omitted.
lifecycle_state...oodmem.v1.ApiKeyLifecycleStateOUTPUT_ONLY; precise lifecycle at the response's evaluation instant.
ceiling_omittedboolOUTPUT_ONLY; true only when a BASIC projection intentionally omitted `ceiling`. When false,
SCOPED keys have a nonempty complete ceiling and inheriting keys have an empty ceiling. When
true, `ceiling` is empty and clients must not infer whether persisted ceiling rules exist.
created_atgoogle.protobuf.TimestampOUTPUT_ONLY; creation timestamp (UTC).
updated_atgoogle.protobuf.TimestampOUTPUT_ONLY; last modification timestamp (UTC).
created_by_idbytesOUTPUT_ONLY; exact creator actor UUID (16 bytes).
updated_by_idbytesOUTPUT_ONLY; exact last-modifier actor UUID (16 bytes).

ApiKey.LabelsEntry

FieldTypeDescription
keystring
valuestring

CreateApiKeyRequest

FieldTypeDescription
api_key_idbytesOPTIONAL; client-provided UUID (16 bytes). The server generates one when omitted.
labels...reateApiKeyRequest.LabelsEntryOPTIONAL; at most 20 labels; keys/values at most 255 characters; keys use [a-z0-9._-].
expires_atgoogle.protobuf.TimestampOPTIONAL; exclusive expiration time (UTC). Must be later than valid_from, which defaults to
issuance time when omitted.
subject_principal_idbytesOPTIONAL; active HUMAN or SERVICE subject; defaults to the request principal.
authority_modegoodmem.v1.ApiKeyAuthorityModeOPTIONAL; UNSPECIFIED defaults to INHERIT_SUBJECT. A scoped issuer may request only SCOPED.
ceilinggoodmem.v1.AccessPolicyRuleOPTIONAL; required and nonempty for SCOPED; prohibited for INHERIT_SUBJECT; at most 1,000
rules. Every rule must be covered by both the subject's live authority and the issuer's
effective authority.
valid_fromgoogle.protobuf.TimestampOPTIONAL; inclusive activation time; defaults to issuance time.

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.ApiKeyOUTPUT_ONLY; created API-key metadata, excluding raw and hashed key material.
raw_api_keystringOUTPUT_ONLY; one-time raw API key. The client must save it immediately.

GetApiKeyRequest

Request to retrieve one API-key resource by UUID.

FieldTypeDescription
api_key_idbytesREQUIRED; UUID (16 bytes) of the credential to retrieve.

GetApiKeyResponse

Response containing complete non-secret API-key metadata.

FieldTypeDescription
api_keygoodmem.v1.ApiKeyOUTPUT_ONLY; requested credential with ceiling_omitted=false.

ListApiKeysRequest

FieldTypeDescription
max_resultsint32OPTIONAL; FULL defaults to 10 and permits at most 20; BASIC defaults to 50 and permits 1,000.
next_tokenstringOPTIONAL; opaque token returned by the preceding page. Do not construct or parse it.
subject_principal_idbytesOPTIONAL; exact subject-principal UUID filter. An absent principal produces an empty page.
owner_principal_idbytesOPTIONAL; exact administrative-owner UUID filter. An absent principal produces an empty page.
lifecycle_state...oodmem.v1.ApiKeyLifecycleStateOPTIONAL; precise lifecycle at the current page's server-selected evaluation instant. An
explicitly supplied UNSPECIFIED value is invalid; omission includes every lifecycle state.
viewgoodmem.v1.ApiKeyViewOPTIONAL; response projection. Omission defaults to FULL; explicitly supplied UNSPECIFIED is
invalid.

ListApiKeysResponse

FieldTypeDescription
keysgoodmem.v1.ApiKeyOUTPUT_ONLY; one stable UUID-ordered page; raw key material is never included.
next_tokenstringOUTPUT_ONLY; opaque continuation token, absent after the final page.

ListApiKeysNextPageToken

Opaque API-key page cursor encoded and validated by the server.

FieldTypeDescription
requestor_idbytes
authenticating_api_key_idbytes
last_api_key_idbytes
subject_principal_idbytes
owner_principal_idbytes
lifecycle_state...oodmem.v1.ApiKeyLifecycleState
viewgoodmem.v1.ApiKeyView

UpdateApiKeyRequest

FieldTypeDescription
api_key_idbytesREQUIRED; UUID (16 bytes) of the key to update.
replace_labelsgoodmem.v1.StringMapOPTIONAL; replaces all labels. An empty StringMap clears all labels. The replacement may
contain at most 20 entries; keys/values may contain at most 255 characters; keys use
[a-z0-9._-].
See: goodmem.v1.StringMap
merge_labelsgoodmem.v1.StringMapOPTIONAL; upserts labels with overwrite while preserving unmentioned labels. The final
stored map may contain at most 20 entries; keys/values may contain at most 255 characters;
keys use [a-z0-9._-].
See: goodmem.v1.StringMap
statusgoodmem.v1.ApiKeyStatusOPTIONAL; status mutation. UNSPECIFIED is rejected; omission preserves status.

DeleteApiKeyRequest

FieldTypeDescription
api_key_idbytesREQUIRED; UUID (16 bytes) of the key to revoke permanently.

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 cannot authenticate at the response evaluation instant because it is not yet valid, has expired, or was permanently revoked
NameValueDescription
STATUS_UNSPECIFIED0Invalid status; `INVALID_ARGUMENT` on writes
ACTIVE1Key is valid and can be used for authentication
INACTIVE2Key cannot authenticate now: scheduled, expired, or permanently revoked

ApiKeyLifecycleState

Precise API-key lifecycle derived at one server-selected evaluation instant.

Precedence is REVOKED, then NOT_YET_VALID, then EXPIRED, then USABLE. valid_from is inclusive and expires_at is exclusive. This enum supplements the compatibility ApiKeyStatus, whose INACTIVE value combines every currently unusable state.

NameValueDescription
API_KEY_LIFECYCLE_STATE_UNSPECIFIED0
API_KEY_LIFECYCLE_STATE_NOT_YET_VALID1
API_KEY_LIFECYCLE_STATE_USABLE2
API_KEY_LIFECYCLE_STATE_EXPIRED3
API_KEY_LIFECYCLE_STATE_REVOKED4

ApiKeyView

Metadata projection returned by ListApiKeys.

NameValueDescription
API_KEY_VIEW_UNSPECIFIED0Invalid when explicitly supplied. An omitted view defaults to FULL.
API_KEY_VIEW_FULL1Complete metadata, including the immutable scoped-key ceiling.
API_KEY_VIEW_BASIC2Lean metadata with the ceiling deliberately omitted.

ApiKeyAuthorityMode

Determines how an API key derives its effective authorization.

An inheriting key follows the live authority of its HUMAN subject. A scoped key intersects the subject's live authority with the immutable, nonempty ceiling selected when the key is issued.

NameValueDescription
API_KEY_AUTHORITY_MODE_UNSPECIFIED0Create defaults to INHERIT_SUBJECT for compatibility.
API_KEY_AUTHORITY_MODE_INHERIT_SUBJECT1
API_KEY_AUTHORITY_MODE_SCOPED2