Skip to content

Commit 43bbc69

Browse files
Add client-initiated certificate request flow (CSR)
Resolves open-telemetry#13 Uses [Development] label as the indication of the least mature level proposed in this upcoming OTEP: open-telemetry/oteps#232
1 parent 86d892f commit 43bbc69

2 files changed

Lines changed: 223 additions & 1 deletion

File tree

proto/opamp.proto

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ message AgentToServer {
7676

7777
// Bit flags as defined by AgentToServerFlags bit masks.
7878
uint64 flags = 10;
79+
80+
// A request to create connection settings. This field is set for flows where
81+
// the Agent initiates the creation of connection settings.
82+
// Status: [Development]
83+
ConnectionSettingsRequest connection_settings_request = 11;
7984
}
8085

8186
enum AgentToServerFlags {
@@ -98,6 +103,38 @@ enum AgentToServerFlags {
98103
message AgentDisconnect {
99104
}
100105

106+
// ConnectionSettingsRequest is a request from the Agent to the Server to create
107+
// and respond with an offer of connection settings for the Agent.
108+
// Status: [Development]
109+
message ConnectionSettingsRequest {
110+
// Request for OpAMP connection settings. If this field is unset
111+
// then the ConnectionSettingsRequest message is empty and is not actionable
112+
// for the Server.
113+
OpAMPConnectionSettingsRequest opamp = 1;
114+
115+
// In the future we can add request fields for non-OpAMP connection types
116+
// (own telemetry, other connections).
117+
}
118+
119+
// OpAMPConnectionSettingsRequest is a request for the Server to produce
120+
// a OpAMPConnectionSettings in its response.
121+
// Status: [Development]
122+
message OpAMPConnectionSettingsRequest {
123+
// A request to create a client certificate. This is used to initiate a
124+
// Client Signing Request (CSR) flow.
125+
// Required.
126+
CertificateRequest certificate_request = 1;
127+
}
128+
129+
// Status: [Development]
130+
message CertificateRequest {
131+
// PEM-encoded Client Certificate Signing Request (CSR), signed by client's private key.
132+
// The Server SHOULD validate the request and SHOULD respond with a
133+
// OpAMPConnectionSettings where the certificate.public_key contains the issued
134+
// certificate.
135+
bytes csr = 1;
136+
}
137+
101138
message ServerToAgent {
102139
// Agent instance uid. MUST match the instance_uid field in AgentToServer message.
103140
// Used for multiplexing messages from/to multiple agents using one message stream.
@@ -179,6 +216,9 @@ enum ServerCapabilities {
179216
// The Server can offer connection settings.
180217
// Status: [Beta]
181218
ServerCapabilities_OffersConnectionSettings = 0x00000020;
219+
// The Server can accept ConnectionSettingsRequest and respond with an offer.
220+
// Status: [Development]
221+
ServerCapabilities_AcceptsConnectionSettingsRequest = 0x00000040;
182222

183223
// Add new capabilities here, continuing with the least significant unused bit.
184224
}

specification.md

Lines changed: 183 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Status: [Beta]
3737
- [AgentToServer.package_statuses](#agenttoserverpackage_statuses)
3838
- [AgentToServer.agent_disconnect](#agenttoserveragent_disconnect)
3939
- [AgentToServer.flags](#agenttoserverflags)
40+
- [AgentToServer.connection_settings_request](#agenttoserverconnection_settings_request)
4041
+ [ServerToAgent Message](#servertoagent-message)
4142
- [ServerToAgent.instance_uid](#servertoagentinstance_uid)
4243
- [ServerToAgent.error_response](#servertoagenterror_response)
@@ -84,9 +85,14 @@ Status: [Beta]
8485
+ [OpAMP Connection Setting Offer Flow](#opamp-connection-setting-offer-flow)
8586
+ [Trust On First Use](#trust-on-first-use)
8687
+ [Registration On First Use](#registration-on-first-use)
88+
+ [Agent-initiated CSR Flow](#agent-initiated-csr-flow)
89+
- [Using instance_uid in the CSR](#using-instance_uid-in-the-csr)
8790
+ [Revoking Access](#revoking-access)
8891
+ [Certificate Generation](#certificate-generation)
8992
+ [Connection Settings for "Other" Destinations](#connection-settings-for-other-destinations)
93+
+ [ConnectionSettingsRequest Message](#connectionsettingsrequest-message)
94+
+ [OpAMPConnectionSettingsRequest Message](#opampconnectionsettingsrequest-message)
95+
+ [CertificateRequest Message](#certificaterequest-message)
9096
+ [ConnectionSettingsOffers Message](#connectionsettingsoffers-message)
9197
- [ConnectionSettingsOffers.hash](#connectionsettingsoffershash)
9298
- [ConnectionSettingsOffers.opamp](#connectionsettingsoffersopamp)
@@ -464,6 +470,7 @@ message AgentToServer {
464470
PackageStatuses package_statuses = 8;
465471
AgentDisconnect agent_disconnect = 9;
466472
uint64 flags = 10;
473+
ConnectionSettingsRequest connection_settings_request = 11; // Status: [Development]
467474
}
468475
```
469476

@@ -607,6 +614,15 @@ enum AgentToServerFlags {
607614
}
608615
```
609616

617+
##### AgentToServer.connection_settings_request
618+
619+
Status: [Development]
620+
621+
A request to create connection settings. This field is set for flows where
622+
the Agent initiates the creation of connection settings.
623+
624+
See [ConnectionSettingsRequest](#connectionsettingsrequest-message) message for details.
625+
610626
#### ServerToAgent Message
611627

612628
The body of the WebSocket message or HTTP response body is a binary serialized
@@ -754,6 +770,9 @@ enum ServerCapabilities {
754770
// The Server can offer connection settings.
755771
// Status: [Beta]
756772
OffersConnectionSettings = 0x00000020;
773+
// The Server can accept ConnectionSettingsRequest and respond with an offer.
774+
// Status: [Development]
775+
AcceptsConnectionSettingsRequest = 0x00000040;
757776
758777
// Add new capabilities here, continuing with the least significant unused bit.
759778
}
@@ -1358,9 +1377,13 @@ of connection settings for "other" destinations is described in
13581377
[Connection Settings for "Other" Destinations](#connection-settings-for-other-destinations).
13591378
The handling of OpAMP connection settings is described below.
13601379

1380+
It is also possible the Agent to make a request the Server to initiate the connection
1381+
settings creation. This process is described in
1382+
[Agent-initiated CSR Flow](#agent-initiated-csr-flow) section.
1383+
13611384
#### OpAMP Connection Setting Offer Flow
13621385

1363-
Here is how the OpAMP connection settings change happens:
1386+
Here is how the server-initiated OpAMP connection settings change happens:
13641387

13651388
```
13661389
Client Server
@@ -1458,6 +1481,113 @@ immediately after successful connection each Agent will acquire their own unique
14581481
connection credentials. This way individual Agent's credentials may be revoked
14591482
without disrupting the access to all other Agents.
14601483

1484+
#### Agent-initiated CSR Flow
1485+
1486+
This is an Agent-initiated flow that allows the Client to send a Certificate
1487+
Signing Request (CSR) to the Server and obtain a self-signed or CA-signed client
1488+
certificate that the Client can use for subsequent OpAMP connections.
1489+
1490+
This flow is currently only supported for OpAMP connections. It is not possible
1491+
for the Agent to send a CSR request for own telemetry connection or for other
1492+
connections types.
1493+
1494+
```
1495+
Client Server
1496+
1497+
│ (1) Connect │
1498+
├──────────────────────────────────────►│
1499+
│ ... │
1500+
┌───────────┐ │ │ ┌───────────┐
1501+
│ Generate │ (2) │ (3) AgentToServer{CSR} │(4) │ │
1502+
│ Keypair ├───────►├──────────────────────────────────────►├─────────►│ Approve │
1503+
│ and CSR │ │ ... │ │ │
1504+
└───────────┘ │ │ └─────┬─────┘
1505+
│ │ │(5)
1506+
│ │ │
1507+
│ │ ▼
1508+
│ │ ┌───────────┐
1509+
┌───────────┐ │ServerToAgent{ConnectionSettingsOffers}│ (7) │Create │
1510+
│ │◄───────┤◄──────────────────────────────────────┤◄─────────┤Certificate│
1511+
│Credentials│ Save │ │ │ (6) │
1512+
│ Store │ │ Disconnect │ └───────────┘
1513+
│ ├───────►├──────────────────────────────────────►│
1514+
└───────────┘ │ │
1515+
│ Connect, New settings │ ┌───────────┐
1516+
├──────────────────────────────────────►├─────────►│ │
1517+
│ │ Delete │Credentials│
1518+
┌───────────┐ │ Connection established │ old │ Store │
1519+
│ │◄───────┤◄─────────────────────────────────────►│◄─────────┤ │
1520+
│Credentials│Delete │ │ └───────────┘
1521+
│ Store │old (8) │ │
1522+
│ ├───────►│ │
1523+
└───────────┘ │ │
1524+
```
1525+
1526+
The sequence is the following:
1527+
- (1) The Client connects to the Server. The Client SHOULD use a regular TLS, validating
1528+
the Server's identity. The Agent may also use a bootstrap client certificate that is
1529+
already trusted by the Server. (Note: the distribution and installation method of
1530+
the bootstrap certificate is not part of this specification).
1531+
- (2) The Agent generates a keypair and a Certificate Signing Request (CSR). The CSR
1532+
contains the information that client wants to use for subsequent authentication.
1533+
- (3) The Client sends an AgentToServer message containing the CSR.
1534+
- (4) If a bootstrap certificate is provided the Server validates it (e.g. with a
1535+
trusted CA) and awaits for an approval to generate a client certificate for the Agent.
1536+
- (5) The Server either waits for a manual approval by a human or automatically
1537+
approves all TOFU requests if the Server is configured to do so (can be a
1538+
Server-side option).
1539+
- (6) Once approved the Server creates a client certificate. The Server does this
1540+
either by issuing a self-signed certificate (acting as a local CA) or proxies the
1541+
CSR to a CA and obtains a client certificate from the CA.
1542+
- After obtaining the client certificate from the CA the flow is essentially
1543+
identical to [OpAMP Connection Setting Offer Flow](#opamp-connection-setting-offer-flow)
1544+
steps, starting by offering the connection settings that carry the created client
1545+
certificate (7). The OpAMPConnectionSettings.certificate message will have the
1546+
public_key field set to the client certificate. If a CA is used the ca_public_key field
1547+
will be set to the CA's public key. The private_key field will not be set, since in
1548+
this flow the Agent possesses the private key and the Server does not possess it.
1549+
- (8) Upon successful completion of verification of the offered new client certificate,
1550+
the Agent removes the bootstrap certificate.
1551+
1552+
When sending OpAMPConnectionSettings to the Agent the Server MAY include fields
1553+
other than `certificate`, thus enabling the Server to replace Agent's certificate,
1554+
connection headers and other settings at once.
1555+
1556+
If any of the steps 4-6 fails the Server MUST respond to the Agent with a
1557+
[ServerErrorResponse](#servererrorresponse-message) with the `type` field set
1558+
to `ServerErrorResponseType_BadRequest`.
1559+
1560+
##### Using instance_uid in the CSR
1561+
1562+
The implementation may choose to use Agent's instance_uid as one of the CSR fields
1563+
(or part of the field) and the Server may in such implementations verify that the
1564+
connecting Agent's instance_uid in the payloads matches the certificate's content.
1565+
This prevents Agents impersonating other Agents.
1566+
1567+
When the Server receives a CSR containing the instance_uid in CSR fields the Server
1568+
MUST verify that [instance_uid](#agenttoserverinstance_uid) field in AgentToServer
1569+
message matches the instance_uid in the CSR fields. This enforces that the Agent
1570+
may only ask for a certificate for itself.
1571+
1572+
If the instance_uid is part of the CSR and the issued client certificate then any change
1573+
of the instance_uid requires re-generation of the client certificate. Such change is
1574+
possible for example if the Server instructs the Agent to use a new instance_uid
1575+
via [new_instance_uid](#servertoagentagent_identification) field.
1576+
1577+
When instructed by the Server to changes its instance_uid the Agent must also repeat the
1578+
[Agent-initiated CSR Flow](#agent-initiated-csr-flow) this time using the new
1579+
instance_uid as one of the CSR fields. The Server must be ready to receive a CSR like
1580+
that, while the Agent is still using the old certificate that contains the old
1581+
instance_uid.
1582+
1583+
In other words: an incoming CSR may ask for a new certificate that references an
1584+
instance_uid that is different from the instance_uid that is referenced in the
1585+
client certificate that is used by that same incoming connection. This is a valid
1586+
situation and must not be rejected by the Server. In this situation the Server may
1587+
also look at the instance_uid in the connecting client certificate and compare it
1588+
to the old known instance_uid to confirm that the Agent is indeed performing
1589+
an instance_uid change as instructed by the Server.
1590+
14611591
#### Revoking Access
14621592

14631593
Since the Server knows what access headers and a client certificate the Client
@@ -1494,6 +1624,58 @@ OpAMP specification.
14941624

14951625
TBD
14961626

1627+
#### ConnectionSettingsRequest Message
1628+
1629+
Status: [Development]
1630+
1631+
ConnectionSettingsRequest is a request from the Agent to the Server to create
1632+
and respond with an offer of connection settings for the Agent.
1633+
1634+
```protobuf
1635+
message ConnectionSettingsRequest {
1636+
OpAMPConnectionSettingsRequest opamp = 1;
1637+
}
1638+
```
1639+
1640+
`opamp` field is set to indicate a request for OpAMP connection settings.
1641+
If this field is unset then the ConnectionSettingsRequest message is empty and is
1642+
not actionable for the Server.
1643+
1644+
#### OpAMPConnectionSettingsRequest Message
1645+
1646+
Status: [Development]
1647+
1648+
OpAMPConnectionSettingsRequest is a request for the Server to produce
1649+
a OpAMPConnectionSettings in its response.
1650+
1651+
Used for [Agent-initiated CSR Flow](#agent-initiated-csr-flow).
1652+
1653+
```protobuf
1654+
message OpAMPConnectionSettingsRequest {
1655+
CertificateRequest certificate_request = 1;
1656+
}
1657+
```
1658+
1659+
certificate_request is set when the Agent requests the Server to create a client
1660+
certificate. This field is required.
1661+
1662+
#### CertificateRequest Message
1663+
1664+
Status: [Development]
1665+
1666+
```protobuf
1667+
message CertificateRequest {
1668+
bytes csr = 1;
1669+
}
1670+
```
1671+
1672+
`csr` field is the PEM-encoded Client Certificate Signing Request (CSR), signed by
1673+
client's private key.
1674+
1675+
The Server SHOULD validate the request and SHOULD respond with a
1676+
OpAMPConnectionSettings where the certificate.public_key contains the issued
1677+
certificate.
1678+
14971679
#### ConnectionSettingsOffers Message
14981680

14991681
ConnectionSettingsOffers message describes connection settings for the Agent to

0 commit comments

Comments
 (0)