Skip to content

Commit

Permalink
Replace ULIDs by 16 byte ids and recommend UUID v7
Browse files Browse the repository at this point in the history
The early version of the spec was written before UUID v7 existed and
ULID was chosen as a ID type that is suited to be used as a primary
key in databases. Since than UUID v7 was standardized and aims to
serve the exact same niche.

## Proposal

Replace instance_id definition to be an arbitrary sequence of 16 bytes.
Both ULID and any version of UUID may be used as the value. We also
recommend to use UUID v7 for the value.

This is a breaking change in the spec. We recommend opamp-go implementation
to implement the change in backward compatible way, supporting both old and
new instance_uid formats for a period of time.

Since `bytes` and `string` are compatible in the Protobuf wire encoding
it is possible to use the new Protobuf declarations to receive messages
encoded using the old Protobuf declarations - string's UTF8 bytes
will simply populate the bytes of the new field. Receivers can simply
probe for the length of the received bytes field and if it is 26 treat
it as ULID in canonical format, if it is 16 bytes treat it as opaque
id in new format, otherwise consider it invalid.

I will also post a PR in opamp-go that implements the above behavior.
  • Loading branch information
tigrannajaryan committed Apr 17, 2024
1 parent 0a32d93 commit 7c4c461
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 12 deletions.
9 changes: 5 additions & 4 deletions proto/opamp.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ option go_package = "github.com/open-telemetry/opamp-go/protobufs";
message AgentToServer {
// Globally unique identifier of the running instance of the Agent. SHOULD remain
// unchanged for the lifetime of the Agent process.
// Recommended format: https://github.com/ulid/spec
string instance_uid = 1;
// MUST be 16 bytes long and SHOULD be generated using UUID v7 spec.
bytes instance_uid = 1;

// The sequence number is incremented by 1 for every AgentToServer sent
// by the Agent. This allows the Server to detect that it missed a message when
Expand Down Expand Up @@ -148,7 +148,7 @@ message CertificateRequest {
message ServerToAgent {
// Agent instance uid. MUST match the instance_uid field in AgentToServer message.
// Used for multiplexing messages from/to multiple agents using one message stream.
string instance_uid = 1;
bytes instance_uid = 1;

// error_response is set if the Server wants to indicate that something went wrong
// during processing of an AgentToServer message. If error_response is set then
Expand Down Expand Up @@ -804,7 +804,8 @@ enum PackageStatusEnum {
message AgentIdentification {
// When new_instance_uid is set, Agent MUST update instance_uid
// to the value provided and use it for all further communication.
string new_instance_uid = 1;
// MUST be 16 bytes long and SHOULD be generated using UUID v7 spec.
bytes new_instance_uid = 1;
}

/////////////////////////////////////////////////////////////////////////////////////
Expand Down
16 changes: 8 additions & 8 deletions specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ document are specified in

```protobuf
message AgentToServer {
string instance_uid = 1;
bytes instance_uid = 1;
uint64 sequence_num = 2;
AgentDescription agent_description = 3;
uint64 capabilities = 4;
Expand All @@ -504,9 +504,9 @@ The instance_uid field is a globally unique identifier of the running instance
of the Agent. The Agent SHOULD self-generate this identifier and make the best
effort to avoid creating an identifier that may conflict with identifiers
created by other Agents. The instance_uid SHOULD remain unchanged for the
lifetime of the Agent process. The instance_uid MUST be a
[ULID](https://github.com/ulid/spec) formatted as a 26 character string in canonical
representation.
lifetime of the Agent process. The instance_uid MUST be
16 bytes long and SHOULD be generated using
[UUID v7 spec](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-14.html#name-uuid-version-7).

In case the Agent wants to use an identifier generated by the Server, the field
SHOULD be set with a temporary value and RequestInstanceUid flag MUST be set.
Expand Down Expand Up @@ -704,7 +704,7 @@ The ServerToAgent message has the following structure:

```protobuf
message ServerToAgent {
string instance_uid = 1;
bytes instance_uid = 1;
ServerErrorResponse error_response = 2;
AgentRemoteConfig remote_config = 3;
ConnectionSettingsOffers connection_settings = 4; // Status: [Beta]
Expand Down Expand Up @@ -826,12 +826,12 @@ enum ServerCapabilities {
Properties related to identification of the Agent, which can be overridden by the
Server if needed. When new_instance_uid is set, Agent MUST update instance_uid
to the value provided and use it for all further communication. The new_instance_uid MUST
be a [ULID](https://github.com/ulid/spec) formatted as a 26 character string in canonical
representation.
be 16 bytes long and SHOULD be generated using
[UUID v7 spec](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-14.html#name-uuid-version-7).

```protobuf
message AgentIdentification {
string new_instance_uid = 1;
bytes new_instance_uid = 1;
}
```

Expand Down

0 comments on commit 7c4c461

Please sign in to comment.