Extension
gRPC ExtensionService reference for CreateExtension, GetExtension, DownloadExtension, ListExtensions and other RPCs, with request messages, response types, and service documentation.
Services
ExtensionService Service
Service for managing Extensions in the GoodMem system.
Extensions are JAR-based plugins that enhance GoodMem functionality with post-processors and custom logic components. This service provides lifecycle management including upload, download, metadata retrieval, listing, and deletion operations.
Authentication: gRPC metadata x-api-key: <api-key>
Global errors: All RPCs may return DEADLINE_EXCEEDED, CANCELLED, UNAVAILABLE, RESOURCE_EXHAUSTED, INTERNAL.
Authorization model:
- Every RPC evaluates a typed authorization operation against the GoodMem instance or a particular extension.
- ROOT and ADMIN receive extension-management authority by default; the standard USER role receives none, because uploaded JARs execute inside the server process. An administrator may delegate individual extension operations through direct authorization grants.
- Ownership, code-defined role assignments, and direct grants can supply authority; an API-key ceiling may further restrict the authenticated principal's effective authority.
- Listing requires
LIST_EXTENSIONon the instance and returns only extensions on which the caller hasREAD_EXTENSION.
Security considerations:
- Binary JAR content is separated from metadata for security and performance
- Download operations require separate permissions from metadata access
- Murmur3 hashing detects accidental corruption only; it is not a signature and does not establish that plugin code is trusted
CreateExtension
Creates a new Extension by uploading a plugin file.
| Type | |
|---|---|
| Request | goodmem.v1.CreateExtensionRequest |
| Response | goodmem.v1.Extension |
Auth: gRPC metadata x-api-key: <api-key>
Authorization Required: CREATE_EXTENSION on the proposed extension, evaluated using its
proposed owner.
Summary:
- Owner defaults to the authenticated principal unless
owner_idis provided; authorization is evaluated against that proposed owner ALREADY_EXISTS: another extension exists with identical{owner_id, extension_type, display_name}combination- Calculates Murmur3 32-bit x86 hash (8-char lowercase hex, seed=0) for corruption detection
- Sets default
statusto"ACTIVE"andmedia_typeto"application/java-archive"if not provided
Side Effects:
- Persists extension with binary content; sets audit fields
Error Codes:
UNAUTHENTICATED: missing/invalid authPERMISSION_DENIED: lacksCREATE_EXTENSIONon the proposed extensionINVALID_ARGUMENT: empty/invalid fields; unsupportedextension_type; emptyplugin_content; file size exceeds server limitsALREADY_EXISTS: matching extension as defined aboveINTERNAL: unexpected server error
Idempotency: Non-idempotent; clients SHOULD NOT blindly retry on unknown failures.
Examples:
grpcurl -plaintext \
-H 'x-api-key: gm_xxx' \
-d '{
"display_name": "Custom Processor",
"extension_type": "JAVA_PROCESSOR",
"filename": "my-processor.jar",
"plugin_content": "BASE64_JAR_CONTENT_HERE"
}' \
localhost:8080 goodmem.v1.ExtensionService/CreateExtensionNote: bytes fields in JSON must be base64.
GetExtension
Retrieves metadata of a specific Extension (without plugin content).
| Type | |
|---|---|
| Request | goodmem.v1.GetExtensionRequest |
| Response | goodmem.v1.Extension |
Auth: gRPC metadata x-api-key: <api-key>
Authorization Required: READ_EXTENSION on the requested extension.
Side Effects: None
Error Codes:
UNAUTHENTICATED: missing/invalid authPERMISSION_DENIED: lacksREAD_EXTENSIONon the requested extensionINVALID_ARGUMENT: invalid extension ID formatNOT_FOUND: extension does not existINTERNAL: unexpected server error
Idempotency: Read-only; safe to retry; results may change over time.
Examples:
grpcurl -plaintext \
-H 'x-api-key: gm_xxx' \
-d '{ "extension_id": "BASE64_UUID_BYTES_HERE" }' \
localhost:8080 goodmem.v1.ExtensionService/GetExtensionNote: bytes fields in JSON must be base64.
DownloadExtension
Downloads the plugin content of a specific Extension.
| Type | |
|---|---|
| Request | goodmem.v1.DownloadExtensionRequest |
| Response | goodmem.v1.DownloadExtensionResponse |
Auth: gRPC metadata x-api-key: <api-key>
Authorization Required: DOWNLOAD_EXTENSION on the requested extension.
Security:
- Returns binary JAR content with integrity hash for verification
- Separate download permission required from metadata access
- Download permissions are independent of extension status (
ACTIVE/INACTIVE/DISABLED) - This allows downloading for debugging/forensic purposes even when extensions are disabled
Side Effects: None
Error Codes:
UNAUTHENTICATED: missing/invalid authPERMISSION_DENIED: lacksDOWNLOAD_EXTENSIONon the requested extensionINVALID_ARGUMENT: invalid extension ID formatNOT_FOUND: extension does not existINTERNAL: unexpected server error
Idempotency: Read-only; safe to retry; content is immutable.
Examples:
grpcurl -plaintext \
-H 'x-api-key: gm_xxx' \
-d '{ "extension_id": "BASE64_UUID_BYTES_HERE" }' \
localhost:8080 goodmem.v1.ExtensionService/DownloadExtensionNote: bytes fields in JSON must be base64.
ListExtensions
Lists Extensions accessible to the authenticated principal.
| Type | |
|---|---|
| Request | goodmem.v1.ListExtensionsRequest |
| Response | goodmem.v1.ListExtensionsResponse |
Auth: gRPC metadata x-api-key: <api-key>
Authorization Required: LIST_EXTENSION on the GoodMem instance and READ_EXTENSION on
each returned extension; results include only extensions the caller may read.
Request Parameters:
owner_id(optional, bytes UUID): filter the already-authorized result set by ownername_filter(optional): glob pattern matching ondisplay_name; supports*(any chars),?(single char),\(escape); full-string match; case-sensitive- Pagination: opaque tokens bind the offset, authenticated principal, owner/name filters,
and the fixed sort contract. A malformed token or one reused with a different principal or
explicit filter returns
INVALID_ARGUMENT. - Sorting: by
created_atdescending (newest first), thenextension_iddescending
Note: bytes fields in JSON must be base64.
Side Effects: None
Error Codes:
UNAUTHENTICATED: missing/invalid authPERMISSION_DENIED: lacks instance-levelLIST_EXTENSIONINVALID_ARGUMENT: invalid filters or parametersINTERNAL: unexpected server error
Idempotency: Read-only; safe to retry; results may change over time.
Examples:
grpcurl -plaintext \
-H 'x-api-key: gm_xxx' \
-d '{ "name_filter": "processor*", "max_results": 10 }' \
localhost:8080 goodmem.v1.ExtensionService/ListExtensionsDeleteExtension
Permanently deletes an Extension and its binary content.
| Type | |
|---|---|
| Request | goodmem.v1.DeleteExtensionRequest |
| Response | google.protobuf.Empty |
Auth: gRPC metadata x-api-key: <api-key>
Authorization Required: DELETE_EXTENSION on the requested extension.
Side Effects:
- Removes the extension record and binary JAR content permanently
Error Codes:
UNAUTHENTICATED: missing/invalid authPERMISSION_DENIED: lacksDELETE_EXTENSIONon the requested extensionINVALID_ARGUMENT: invalid extension ID formatNOT_FOUND: extension does not existINTERNAL: 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 '{ "extension_id": "BASE64_UUID_BYTES_HERE" }' \
localhost:8080 goodmem.v1.ExtensionService/DeleteExtensionNote: bytes fields in JSON must be base64.
Messages
Extension
Represents a plugin (JAR file) that extends GoodMem functionality.
Extensions are JAR files containing post-processors, custom logic, or other plugin implementations that integrate with the GoodMem system. Each extension has metadata, security constraints, and lifecycle management through admin-controlled status transitions.
Security:
plugin_content(binary JAR data) is intentionally excluded from this message for security and performance reasons. UseDownloadExtensionto retrieve binary content.
Immutability:
extension_typeis effectively immutable (no update operations supported).owner_idis set at creation and cannot be modified.
Duplicate Prevention:
- System prevents duplicate extensions with identical
{owner_id, extension_type, display_name}. display_namecomparison is case-sensitive after leading/trailing whitespace trimming (no Unicode normalization applied).
Notes:
- All timestamps are UTC (
google.protobuf.Timestamp). - Murmur3 32-bit hash provides corruption detection for JAR content (not cryptographically secure).
See also: ExtensionService for management operations
| Field | Type | Description |
|---|---|---|
extension_id | bytes | OUTPUT_ONLY UUID (16 bytes); immutable primary identifier |
display_name | string | REQUIRED on create; ≤255 chars; leading/trailing whitespace trimmed; cannot be empty |
description | string | OPTIONAL description of extension functionality |
extension_type | string | REQUIRED extension type string; current valid values: "JAVA_PROCESSOR" |
filename | string | REQUIRED original filename of uploaded JAR; ≤255 UTF-8 bytes; cannot be empty after trimming; no path separators or control characters |
media_type | string | OUTPUT_ONLY MIME type; always non-empty; defaults to "application/java-archive" if not provided at create |
file_size | int64 | OUTPUT_ONLY size in bytes of JAR content; set during creation |
file_hash | string | OUTPUT_ONLY Murmur3 32-bit x86 hash (8-char lowercase hex, seed=0) for corruption detection only (not cryptographically secure); calculated during creation |
status | string | OUTPUT_ONLY lifecycle status; valid values: "ACTIVE", "INACTIVE", "DISABLED"; defaults to "ACTIVE"; admin-controlled via tooling only (no RPC for status changes); typical transitions: ACTIVE↔INACTIVE, →DISABLED |
owner_id | bytes | OUTPUT_ONLY owner UUID (16 bytes); set at create; not updatable |
created_at | google.protobuf.Timestamp | Standard audit fields OUTPUT_ONLY |
updated_at | google.protobuf.Timestamp | OUTPUT_ONLY |
created_by_id | bytes | OUTPUT_ONLY creator UUID (16 bytes) |
updated_by_id | bytes | OUTPUT_ONLY last updater UUID (16 bytes) |
CreateExtensionRequest
| Field | Type | Description |
|---|---|---|
extension_id | bytes | Optional client-provided UUID (16 bytes); server generates if omitted; returns ALREADY_EXISTS if ID exists |
display_name | string | Required: User-facing name (≤255 chars; leading/trailing whitespace trimmed; cannot be empty) |
description | string | Optional description of extension functionality |
extension_type | string | Required: Extension type string; current valid values: "JAVA_PROCESSOR" |
filename | string | Required: Original filename (≤255 UTF-8 bytes; cannot be empty after trimming; no path separators or control characters) |
media_type | string | Optional: MIME type (lowercased); empty defaults to "application/java-archive"; must be valid IANA type if provided |
plugin_content | bytes | Required: Binary JAR file content (cannot be empty; subject to server configuration, default limit 100MB) |
owner_id | bytes | Optional owner principal UUID (16 bytes); if omitted → authenticated principal; CREATE_EXTENSION is evaluated using this proposed owner |
GetExtensionRequest
| Field | Type | Description |
|---|---|---|
extension_id | bytes | Required: Extension ID (16 bytes UUID) |
DownloadExtensionRequest
| Field | Type | Description |
|---|---|---|
extension_id | bytes | Required: Extension ID (16 bytes UUID) |
DownloadExtensionResponse
| Field | Type | Description |
|---|---|---|
filename | string | Original filename of the JAR file |
media_type | string | MIME type (e.g., "application/java-archive") |
file_size | int64 | Size in bytes of `plugin_content` |
file_hash | string | Murmur3 32-bit x86 hash (8-char lowercase hex, seed=0) for corruption detection only (not cryptographically secure) |
plugin_content | bytes | Binary JAR file content |
ListExtensionsRequest
| Field | Type | Description |
|---|---|---|
owner_id | bytes | Optional filters Optional: Filter by owner (16 bytes UUID) |
name_filter | string | Optional: Glob pattern for display_name matching; supports * (any chars), ? (single char), \ (escape); full-string match; case-sensitive |
max_results | int32 | Pagination Optional: Max results per page; defaults to 50 if not provided or ≤0 |
next_token | string | Optional: Opaque pagination token; do not parse |
sort_by | string | Sorting (parameters currently ignored by implementation) Optional: Sort field name; IGNORED - implementation always sorts by "created_at" |
sort_order | goodmem.v1.SortOrder | Optional: Sort direction; IGNORED - implementation always uses DESCENDING |
ListExtensionsResponse
| Field | Type | Description |
|---|---|---|
extensions | goodmem.v1.Extension | Page of extension results (metadata only, no binary content) |
next_token | string | Opaque token for next page; omitted on final page |
ListExtensionsNextPageToken
INTERNAL: State carried by an opaque ListExtensions pagination token.
The server validates the requestor, filters, and fixed sort contract before using start.
Clients must not construct or inspect this message; they should return the encoded token exactly
as received. max_results is intentionally excluded so callers may change page size between
pages.
| Field | Type | Description |
|---|---|---|
start | int32 | Required positive offset for the next page |
owner_id | bytes | Effective owner filter from the first page |
name_filter | string | Effective name glob from the first page |
requestor_id | bytes | Authenticated principal UUID (16 bytes) |
sort_by | string | Fixed server sort field (`created_at`) |
sort_order | goodmem.v1.SortOrder | Fixed server sort direction (`DESCENDING`) |
secondary_sort_by | string | Stable tie-breaker field (`extension_id`) |
secondary_sort_order | goodmem.v1.SortOrder | Tie-breaker direction (`DESCENDING`) |
DeleteExtensionRequest
| Field | Type | Description |
|---|---|---|
extension_id | bytes | Required: Extension ID to delete (16 bytes UUID) |
Embedder
gRPC EmbedderService reference for CreateEmbedder, GetEmbedder, ListEmbedders, UpdateEmbedder and other RPCs, with request messages, response types, and service documentation.
Llm
gRPC LLMService reference for CreateLLM, GetLLM, ListLLMs, UpdateLLM and other RPCs, with request messages, response types, and service documentation.