Skip to content

Commit 1e572db

Browse files
danielpaulusclaude
andcommitted
docs(ssl): accurate assertion value types / comparison sets (review)
Daniel-review: the property value-type taxonomy collapsed version/enum/id into 'string', wrongly implying CONTAINS/NOT_CONTAINS on exact-match properties and hiding tlsVersion's GREATER_THAN/LESS_THAN ordering. Split into number / version / string / exact / list / boolean with an accurate comparison table, and document the RESPONSE_TIME / JSON_RESPONSE / TEXT_RESPONSE comparison sets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013AYwkvoaANQTH5dGStbBj2
1 parent ce3ac03 commit 1e572db

2 files changed

Lines changed: 24 additions & 12 deletions

File tree

constructs/ssl-monitor.mdx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,9 @@ Define `assertions` using the `SslAssertionBuilder`. Five entry points map to th
287287
| `jsonResponse(jsonPath)` | `JSON_RESPONSE` | Assert on any response field via a JSONPath expression |
288288
| `textResponse(regex?)` | `TEXT_RESPONSE` | Extract a value from the serialized response with a regex, then compare |
289289

290-
`certificate(property)` properties: `daysUntilExpiry` (number), `keySizeBits` (number), `subjectCN` / `issuerCN` / `serialNumber` / `fingerprintSha256` / `issuerFingerprintSha256` / `keyAlgorithm` / `signatureAlgorithm` (string), `sans` (list — use `CONTAINS`), `selfSigned` / `isCA` (boolean).
290+
`certificate(property)` properties: `daysUntilExpiry` / `keySizeBits` (number`EQUALS` / `NOT_EQUALS` / `GREATER_THAN` / `LESS_THAN`), `subjectCN` / `issuerCN` (string — also `CONTAINS` / `NOT_CONTAINS`), `serialNumber` / `fingerprintSha256` / `issuerFingerprintSha256` / `keyAlgorithm` / `signatureAlgorithm` (exact — `EQUALS` / `NOT_EQUALS` only), `sans` (list — `CONTAINS` / `NOT_CONTAINS`), `selfSigned` / `isCA` (boolean`EQUALS`).
291291

292-
`connection(property)` properties: `tlsVersion` / `cipherSuite` / `ocspStatus` / `resolvedIp` (string), `hostnameVerified` / `chainTrusted` / `ocspStapled` (boolean).
292+
`connection(property)` properties: `tlsVersion` (version — `EQUALS` / `NOT_EQUALS` / `GREATER_THAN` / `LESS_THAN`, ordered TLS1.0 < TLS1.3), `cipherSuite` / `resolvedIp` (string — also `CONTAINS` / `NOT_CONTAINS`), `ocspStatus` (exact — `good` / `revoked` / `unknown`), `hostnameVerified` / `chainTrusted` / `ocspStapled` (boolean`EQUALS`).
293293

294294
Examples:
295295

@@ -302,7 +302,8 @@ SslAssertionBuilder.certificate("daysUntilExpiry").greaterThan(30)
302302
SslAssertionBuilder.connection("chainTrusted").equals(true)
303303
// Equivalent to: { source: 'CONNECTION', property: 'chainTrusted', comparison: 'EQUALS', target: 'true' }
304304

305-
// Negotiate TLS 1.3 (use the security baseline's minTLSVersion for a "1.2-or-newer" policy)
305+
// Assert an exact TLS version — tlsVersion is ordered, so greaterThan/lessThan also work
306+
// (the security baseline's minTLSVersion is the usual way to enforce a "1.2-or-newer" floor)
306307
SslAssertionBuilder.connection("tlsVersion").equals(TlsVersion.TLS1_3)
307308
// Equivalent to: { source: 'CONNECTION', property: 'tlsVersion', comparison: 'EQUALS', target: 'TLS1.3' }
308309

detect/uptime-monitoring/ssl-monitors/configuration.mdx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,29 +84,40 @@ Each assertion has a `source`, an optional `property` (a field selector), a `com
8484
| `daysUntilExpiry` | number | Days until the certificate expires |
8585
| `subjectCN` | string | Certificate subject common name |
8686
| `issuerCN` | string | Common name of the certificate issuer |
87-
| `serialNumber` | string | Certificate serial number |
88-
| `fingerprintSha256` | string | SHA-256 fingerprint of the leaf certificate |
89-
| `issuerFingerprintSha256` | string | SHA-256 fingerprint of the issuer certificate |
87+
| `serialNumber` | exact | Certificate serial number |
88+
| `fingerprintSha256` | exact | SHA-256 fingerprint of the leaf certificate |
89+
| `issuerFingerprintSha256` | exact | SHA-256 fingerprint of the issuer certificate |
9090
| `keySizeBits` | number | Leaf certificate public key size in bits |
91-
| `keyAlgorithm` | string | Public key algorithm (e.g. `RSA`, `ECDSA`) |
92-
| `signatureAlgorithm` | string | Leaf certificate signature algorithm (e.g. `SHA256-RSA`, `ECDSA-SHA256`) |
93-
| `sans` | list | Subject Alternative Names — use `CONTAINS` / `NOT_CONTAINS` to test membership |
91+
| `keyAlgorithm` | exact | Public key algorithm (e.g. `RSA`, `ECDSA`) |
92+
| `signatureAlgorithm` | exact | Leaf certificate signature algorithm (e.g. `SHA256-RSA`, `ECDSA-SHA256`) |
93+
| `sans` | list | Subject Alternative Names |
9494
| `selfSigned` | boolean | The leaf certificate is self-signed |
9595
| `isCA` | boolean | The leaf certificate is a CA certificate |
9696

9797
`CONNECTION` `property` values:
9898

9999
| `property` | Type | Description |
100100
|-----------|------|-------------|
101-
| `tlsVersion` | string | Negotiated TLS protocol version (e.g. `TLS1.2`, `TLS1.3`) |
101+
| `tlsVersion` | version | Negotiated TLS protocol version (e.g. `TLS1.2`, `TLS1.3`) |
102102
| `cipherSuite` | string | IANA cipher suite name negotiated during the handshake |
103103
| `hostnameVerified` | boolean | The certificate's SANs cover the monitored hostname |
104104
| `chainTrusted` | boolean | The full certificate chain is trusted by the system root store |
105105
| `ocspStapled` | boolean | A stapled OCSP response was included in the handshake |
106-
| `ocspStatus` | string | Decoded stapled-OCSP status: `good`, `revoked`, or `unknown` |
106+
| `ocspStatus` | exact | Decoded stapled-OCSP status: `good`, `revoked`, or `unknown` |
107107
| `resolvedIp` | string | The IP address the hostname resolved to |
108108

109-
Comparisons follow the property's type: numbers support `EQUALS`, `NOT_EQUALS`, `GREATER_THAN`, `LESS_THAN`; strings add `CONTAINS` / `NOT_CONTAINS`; booleans use `EQUALS`; the `sans` list uses `CONTAINS` / `NOT_CONTAINS`.
109+
The comparisons available depend on the property's type:
110+
111+
| Type | Comparisons |
112+
|------|-------------|
113+
| `number` | `EQUALS`, `NOT_EQUALS`, `GREATER_THAN`, `LESS_THAN` |
114+
| `version` | `EQUALS`, `NOT_EQUALS`, `GREATER_THAN`, `LESS_THAN` (ordered `TLS1.0` < `TLS1.1` < `TLS1.2` < `TLS1.3`) |
115+
| `string` | `EQUALS`, `NOT_EQUALS`, `CONTAINS`, `NOT_CONTAINS` |
116+
| `exact` | `EQUALS`, `NOT_EQUALS` |
117+
| `list` | `CONTAINS`, `NOT_CONTAINS` (SAN membership) |
118+
| `boolean` | `EQUALS` |
119+
120+
The other sources take their own comparison sets: `RESPONSE_TIME` uses the `number` set; `JSON_RESPONSE` accepts `EQUALS`, `NOT_EQUALS`, `GREATER_THAN`, `LESS_THAN`, `CONTAINS`, `NOT_CONTAINS`, `IS_EMPTY`, `NOT_EMPTY`, `IS_NULL`, `NOT_NULL`; `TEXT_RESPONSE` accepts `EQUALS`, `NOT_EQUALS`, `CONTAINS`, `NOT_CONTAINS`, `IS_EMPTY`, `NOT_EMPTY`, `GREATER_THAN`, `LESS_THAN`.
110121

111122
<Note>
112123
Certificate validity, minimum TLS version and minimum key size are also enforced by the security baseline above — reach for assertions when you need an exact value check (a specific issuer, fingerprint pinning, a SAN, etc.).

0 commit comments

Comments
 (0)