tripwire-server 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -13
  3. data/lib/tripwire/server/client.rb +171 -16
  4. data/lib/tripwire/server/crypto_support.rb +49 -0
  5. data/lib/tripwire/server/gate_delivery.rb +298 -0
  6. data/lib/tripwire/server/sealed_token.rb +2 -0
  7. data/lib/tripwire/server/version.rb +1 -1
  8. data/lib/tripwire/server.rb +12 -0
  9. data/spec/README.md +37 -6
  10. data/spec/fixtures/api/fingerprints/detail.json +70 -0
  11. data/spec/fixtures/api/fingerprints/list.json +37 -0
  12. data/spec/fixtures/api/gate/agent-token-verify.json +12 -0
  13. data/spec/fixtures/api/gate/login-session-consume.json +10 -0
  14. data/spec/fixtures/api/gate/login-session-create.json +12 -0
  15. data/spec/fixtures/api/gate/registry-detail.json +45 -0
  16. data/spec/fixtures/api/gate/registry-list.json +47 -0
  17. data/spec/fixtures/api/gate/service-create.json +49 -0
  18. data/spec/fixtures/api/gate/service-detail.json +49 -0
  19. data/spec/fixtures/api/gate/service-disable.json +49 -0
  20. data/spec/fixtures/api/gate/service-update.json +49 -0
  21. data/spec/fixtures/api/gate/services-list.json +51 -0
  22. data/spec/fixtures/api/gate/session-ack.json +10 -0
  23. data/spec/fixtures/api/gate/session-create.json +13 -0
  24. data/spec/fixtures/api/gate/session-poll.json +36 -0
  25. data/spec/fixtures/api/sessions/detail.json +405 -0
  26. data/spec/fixtures/api/sessions/list.json +36 -0
  27. data/spec/fixtures/api/teams/api-key-create.json +21 -0
  28. data/spec/fixtures/api/teams/api-key-list.json +26 -0
  29. data/spec/fixtures/api/teams/api-key-revoke.json +20 -0
  30. data/spec/fixtures/api/teams/api-key-rotate.json +21 -0
  31. data/spec/fixtures/api/teams/team-create.json +14 -0
  32. data/spec/fixtures/api/teams/team-update.json +14 -0
  33. data/spec/fixtures/api/teams/team.json +14 -0
  34. data/spec/fixtures/errors/invalid-api-key.json +3 -3
  35. data/spec/fixtures/errors/missing-api-key.json +2 -2
  36. data/spec/fixtures/errors/not-found.json +4 -4
  37. data/spec/fixtures/errors/validation-error.json +6 -7
  38. data/spec/fixtures/gate-delivery/approved-webhook-payload.valid.json +20 -0
  39. data/spec/fixtures/gate-delivery/delivery-request.json +9 -0
  40. data/spec/fixtures/gate-delivery/env-policy.json +40 -0
  41. data/spec/fixtures/gate-delivery/vector.v1.json +28 -0
  42. data/spec/fixtures/gate-delivery/webhook-signature.json +9 -0
  43. data/spec/fixtures/manifest.json +179 -0
  44. data/spec/fixtures/sealed-token/vector.v1.json +37 -24
  45. data/spec/openapi.json +4904 -768
  46. data/spec/sealed-token.md +36 -17
  47. metadata +36 -14
  48. data/spec/fixtures/public-api/fingerprints/detail.json +0 -40
  49. data/spec/fixtures/public-api/fingerprints/list.json +0 -31
  50. data/spec/fixtures/public-api/sessions/detail.json +0 -47
  51. data/spec/fixtures/public-api/sessions/list.json +0 -33
  52. data/spec/fixtures/public-api/teams/api-key-create.json +0 -18
  53. data/spec/fixtures/public-api/teams/api-key-list.json +0 -23
  54. data/spec/fixtures/public-api/teams/api-key-rotate.json +0 -18
  55. data/spec/fixtures/public-api/teams/team-create.json +0 -11
  56. data/spec/fixtures/public-api/teams/team-update.json +0 -11
  57. data/spec/fixtures/public-api/teams/team.json +0 -11
  58. /data/spec/fixtures/{public-api/teams/api-key-revoke.json → api/gate/agent-token-revoke.json} +0 -0
@@ -0,0 +1,40 @@
1
+ {
2
+ "derive_agent_token_env_key": [
3
+ {
4
+ "service_id": "tripwire",
5
+ "expected": "TRIPWIRE_GATE_AGENT_TOKEN"
6
+ },
7
+ {
8
+ "service_id": "acme-prod",
9
+ "expected": "ACME_PROD_GATE_AGENT_TOKEN"
10
+ }
11
+ ],
12
+ "is_gate_managed_env_var_key": [
13
+ {
14
+ "key": "TRIPWIRE_AGENT_TOKEN",
15
+ "managed": true
16
+ },
17
+ {
18
+ "key": "ACME_PROD_GATE_AGENT_TOKEN",
19
+ "managed": true
20
+ },
21
+ {
22
+ "key": "ACME_API_KEY",
23
+ "managed": false
24
+ }
25
+ ],
26
+ "is_blocked_gate_env_var_key": [
27
+ {
28
+ "key": "PATH",
29
+ "blocked": true
30
+ },
31
+ {
32
+ "key": "npm_config_registry",
33
+ "blocked": true
34
+ },
35
+ {
36
+ "key": "TRIPWIRE_SECRET_KEY",
37
+ "blocked": false
38
+ }
39
+ ]
40
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "version": 1,
3
+ "delivery": {
4
+ "version": 1,
5
+ "algorithm": "x25519-hkdf-sha256/aes-256-gcm",
6
+ "key_id": "LyGqfpvB0SCaX4P0inVpMJTAjCNJVWq_3OE87it2ZYo",
7
+ "public_key": "bn6szfMIS-7pLl01PqvssrrGRoW1SVTkUuqeg0hfrW0"
8
+ },
9
+ "private_key_pkcs8": "MC4CAQAwBQYDK2VuBCIEIL8KtbBiPaNXyTYwgHfrxlH5RQkpHQ41rwkX77or4_eV",
10
+ "payload": {
11
+ "version": 1,
12
+ "outputs": {
13
+ "TRIPWIRE_PUBLISHABLE_KEY": "pk_test_vector",
14
+ "TRIPWIRE_SECRET_KEY": "sk_test_vector"
15
+ },
16
+ "ack_token": "ack_test_vector"
17
+ },
18
+ "envelope": {
19
+ "version": 1,
20
+ "algorithm": "x25519-hkdf-sha256/aes-256-gcm",
21
+ "key_id": "LyGqfpvB0SCaX4P0inVpMJTAjCNJVWq_3OE87it2ZYo",
22
+ "ephemeral_public_key": "Q_5aebzWx6eFzTwWQfb0w_mLOmlelA2saRy4XdzCjEM",
23
+ "salt": "Zaieku8TjeKB-jfdRjlOfBufwGP5BsGY6PYIA1PwcQk",
24
+ "iv": "gf_vsGj9KXTwRobP",
25
+ "ciphertext": "pCDCqi28gW0GpyXNHhhX0koP_vyst774zO2n7WnLF2v36zYTTEonlEzqM3gOYpX3Vff1rsrBtQ_BS7KPmqvxh1ku93tWebjOUXcEu2ExvJxTakv5JtiS-uxcPDgUbNoy-9r-hFYCJsWZx9Bw2E8ohgUeVsGWWVvZXljfODbHRXlqa0it_pbm5ts6",
26
+ "tag": "fhlTs3NfvLN1rTo8-bpyNQ"
27
+ }
28
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "secret": "whsec_test",
3
+ "timestamp": "1735776000",
4
+ "expired_timestamp": "1735775400",
5
+ "now_seconds": 1735776000,
6
+ "raw_body": "{\"event\":\"gate.session.approved\",\"service_id\":\"tripwire\"}",
7
+ "signature": "e31cfe4ad62aa4a5ed4eaa8c31c05af7f6482d276ff43eb466c562d101835b26",
8
+ "invalid_signature": "031cfe4ad62aa4a5ed4eaa8c31c05af7f6482d276ff43eb466c562d101835b26"
9
+ }
@@ -0,0 +1,179 @@
1
+ {
2
+ "fixtures": [
3
+ {
4
+ "file": "errors/missing-api-key.json",
5
+ "path": "/v1/sessions",
6
+ "method": "get",
7
+ "status": "401"
8
+ },
9
+ {
10
+ "file": "errors/invalid-api-key.json",
11
+ "path": "/v1/sessions",
12
+ "method": "get",
13
+ "status": "401"
14
+ },
15
+ {
16
+ "file": "errors/not-found.json",
17
+ "path": "/v1/sessions/{sessionId}",
18
+ "method": "get",
19
+ "status": "404"
20
+ },
21
+ {
22
+ "file": "errors/validation-error.json",
23
+ "path": "/v1/sessions",
24
+ "method": "get",
25
+ "status": "422"
26
+ },
27
+ {
28
+ "file": "api/sessions/list.json",
29
+ "path": "/v1/sessions",
30
+ "method": "get",
31
+ "status": "200"
32
+ },
33
+ {
34
+ "file": "api/sessions/detail.json",
35
+ "path": "/v1/sessions/{sessionId}",
36
+ "method": "get",
37
+ "status": "200"
38
+ },
39
+ {
40
+ "file": "api/fingerprints/list.json",
41
+ "path": "/v1/fingerprints",
42
+ "method": "get",
43
+ "status": "200"
44
+ },
45
+ {
46
+ "file": "api/fingerprints/detail.json",
47
+ "path": "/v1/fingerprints/{visitorId}",
48
+ "method": "get",
49
+ "status": "200"
50
+ },
51
+ {
52
+ "file": "api/teams/team.json",
53
+ "path": "/v1/teams/{teamId}",
54
+ "method": "get",
55
+ "status": "200"
56
+ },
57
+ {
58
+ "file": "api/teams/team-create.json",
59
+ "path": "/v1/teams",
60
+ "method": "post",
61
+ "status": "201"
62
+ },
63
+ {
64
+ "file": "api/teams/team-update.json",
65
+ "path": "/v1/teams/{teamId}",
66
+ "method": "patch",
67
+ "status": "200"
68
+ },
69
+ {
70
+ "file": "api/teams/api-key-create.json",
71
+ "path": "/v1/teams/{teamId}/api-keys",
72
+ "method": "post",
73
+ "status": "201"
74
+ },
75
+ {
76
+ "file": "api/teams/api-key-list.json",
77
+ "path": "/v1/teams/{teamId}/api-keys",
78
+ "method": "get",
79
+ "status": "200"
80
+ },
81
+ {
82
+ "file": "api/teams/api-key-rotate.json",
83
+ "path": "/v1/teams/{teamId}/api-keys/{keyId}/rotations",
84
+ "method": "post",
85
+ "status": "201"
86
+ },
87
+ {
88
+ "file": "api/teams/api-key-revoke.json",
89
+ "path": "/v1/teams/{teamId}/api-keys/{keyId}",
90
+ "method": "delete",
91
+ "status": "200"
92
+ },
93
+ {
94
+ "file": "api/gate/registry-list.json",
95
+ "path": "/v1/gate/registry",
96
+ "method": "get",
97
+ "status": "200"
98
+ },
99
+ {
100
+ "file": "api/gate/registry-detail.json",
101
+ "path": "/v1/gate/registry/{serviceId}",
102
+ "method": "get",
103
+ "status": "200"
104
+ },
105
+ {
106
+ "file": "api/gate/services-list.json",
107
+ "path": "/v1/gate/services",
108
+ "method": "get",
109
+ "status": "200"
110
+ },
111
+ {
112
+ "file": "api/gate/service-detail.json",
113
+ "path": "/v1/gate/services/{serviceId}",
114
+ "method": "get",
115
+ "status": "200"
116
+ },
117
+ {
118
+ "file": "api/gate/service-create.json",
119
+ "path": "/v1/gate/services",
120
+ "method": "post",
121
+ "status": "201"
122
+ },
123
+ {
124
+ "file": "api/gate/service-update.json",
125
+ "path": "/v1/gate/services/{serviceId}",
126
+ "method": "patch",
127
+ "status": "200"
128
+ },
129
+ {
130
+ "file": "api/gate/service-disable.json",
131
+ "path": "/v1/gate/services/{serviceId}",
132
+ "method": "delete",
133
+ "status": "200"
134
+ },
135
+ {
136
+ "file": "api/gate/session-create.json",
137
+ "path": "/v1/gate/sessions",
138
+ "method": "post",
139
+ "status": "201"
140
+ },
141
+ {
142
+ "file": "api/gate/session-poll.json",
143
+ "path": "/v1/gate/sessions/{gateSessionId}",
144
+ "method": "get",
145
+ "status": "200"
146
+ },
147
+ {
148
+ "file": "api/gate/session-ack.json",
149
+ "path": "/v1/gate/sessions/{gateSessionId}/ack",
150
+ "method": "post",
151
+ "status": "200"
152
+ },
153
+ {
154
+ "file": "api/gate/login-session-create.json",
155
+ "path": "/v1/gate/login-sessions",
156
+ "method": "post",
157
+ "status": "201"
158
+ },
159
+ {
160
+ "file": "api/gate/login-session-consume.json",
161
+ "path": "/v1/gate/login-sessions/consume",
162
+ "method": "post",
163
+ "status": "200"
164
+ },
165
+ {
166
+ "file": "api/gate/agent-token-verify.json",
167
+ "path": "/v1/gate/agent-tokens/verify",
168
+ "method": "post",
169
+ "status": "200"
170
+ },
171
+ {
172
+ "file": "api/gate/agent-token-revoke.json",
173
+ "path": "/v1/gate/agent-tokens/revoke",
174
+ "method": "post",
175
+ "status": "204",
176
+ "body": "none"
177
+ }
178
+ ]
179
+ }
@@ -2,40 +2,53 @@
2
2
  "version": 1,
3
3
  "secretKey": "sk_live_fixture_secret",
4
4
  "secretHash": "c173e2c1467e446744e3b6aba8fc07e639008fdf3c4b82e32dceef9b41217dc3",
5
- "token": "Ae06cX3X+GJm5kIEpWCttcHCIVI9o3Y0HWX/clGdryb0XO2K0eIIsEkh3bdtCTKJMfykSJGkECwhajrvmYFjPSPMbs7gSfUeUnKYHX/4hV1SZNkGby8hHvrhPGiXuxOeqwBfTokfhpJrUIMVLhH3DArgNBi9su6VFrdYNoSf9ca8ttWY/mq2fDvQdHoNg8Kg8VNnCTEALVcOOf4TwtLqbp59GRto59rDPQpFtWFtGcCDNCvGsMoBqqdm3gcEsD38nGIiWhasFlr9/1h26qJhDl7Jy4ZYIjhSxLQRv8O/Xj+YBbQvM5NkhgqfrvTVdzQkpuvM3HZawOXw9PP5MowhzLLKWEEPwgJnWbLXqxVmB1IXU6yovT9jNPiYW9bNlAb0QzhNVHfJWsy247VGMVSXEO7FKu3L3JVhuU7HzoV+DNjQXjp3KzwNw7AbzGTEqJGrEgc8WgkbDSpWl86X+jJv6igFf308BT49QcP7GlpklYM+c9olYThBy1+L8Mw=",
5
+ "token": "AQyvpqAj2Es6mvd4vsMZGi4SpmWM/C8VAuASfl/6rQR6kAg2dFEXuWcfLojx8obJCYopv8H+v/b/FPn/+q80KRIFA5+cdsIPmjrHY0Z/rcrB2VIBrm1g0+wMkQnTEJb3VbtlobShig+pa4UQhMohhse30n1bzrGbH+8qVbwKbczz/UowIY+uQ7OI8iBWE3ev+wp9u0kvFDMyJMpgRJHuLSvm3oVBgO+MBmvSTyIrVI5o8f2gKtHuFu0whSgMkvaD9iYmWb6OgHvQdcI8QjkNRMniree81af/sw6p175ntU2lwFCsS+P4hHdUKl4doDJjpZiUnRCGeHrmPtxC02M1oNMfpAGH7y130EsNxl8KVuIyAf5wSr546n0rAOUNtwQtUe6CFg7DdyYgdHJMgUmreGARMQJbHf66ykNLV307UpbfM4IzU7kWD7ampH34HLBLoRBgZhkRfhy5LNsKUEBzVxEEGPJwcJxOOhpqlQEblAdaWduSvbOtPOm8kcNNJTitdjejZOctBtMb/X1QjjdHOxURf9XaXlS3v8y2+vJwPjEa/F+oUj5V/z6tLqm029VHU/snUzhdEs7MQ+Y8ACMQTyWhHLcwBGpo3IWVTv/xl4pz7c0PVKQ=",
6
6
  "payload": {
7
- "eventId": "evt_fixture",
8
- "sessionId": "sid_fixture",
9
- "verdict": "human",
10
- "score": 7,
11
- "manipulationScore": 0,
12
- "manipulationVerdict": "none",
13
- "evaluationDuration": 123,
14
- "scoredAt": 1711310400000,
15
- "metadata": {
16
- "userAgent": "Mozilla/5.0",
7
+ "object": "session_verification",
8
+ "session_id": "sid_0123456789abcdefghjkmnpqrs",
9
+ "decision": {
10
+ "event_id": "evt_0123456789abcdefghjkmnpqrs",
11
+ "verdict": "human",
12
+ "risk_score": 7,
13
+ "phase": "behavioral",
14
+ "is_provisional": false,
15
+ "manipulation": {
16
+ "score": 0,
17
+ "verdict": "none"
18
+ },
19
+ "evaluation_duration_ms": 123,
20
+ "evaluated_at": "2026-03-24T20:00:00.000Z"
21
+ },
22
+ "request": {
23
+ "user_agent": "Mozilla/5.0",
17
24
  "url": "https://example.com/signup",
18
- "screenSize": "1440x900",
19
- "touchDevice": false,
20
- "clientIp": "203.0.113.9"
25
+ "screen_size": "1440x900",
26
+ "is_touch_capable": false,
27
+ "ip_address": "203.0.113.9"
28
+ },
29
+ "visitor_fingerprint": {
30
+ "object": "visitor_fingerprint",
31
+ "id": "vid_0123456789abcdefghjkmnpqrs",
32
+ "confidence": 94,
33
+ "identified_at": "2026-03-24T19:59:59.000Z"
21
34
  },
22
35
  "signals": [
23
36
  {
24
37
  "id": "E6",
25
38
  "category": "environment",
26
- "confidence": "low",
39
+ "confidence": "strong",
27
40
  "score": 20
28
41
  }
29
42
  ],
30
- "categoryScores": {
31
- "behavioral": 9,
32
- "environment": 20
43
+ "score_breakdown": {
44
+ "categories": {
45
+ "behavioral": 9,
46
+ "environment": 20
47
+ }
48
+ },
49
+ "attribution": {
50
+ "bot": null
33
51
  },
34
- "botAttribution": null,
35
- "visitorId": "vis_fixture",
36
- "visitorIdConfidence": 94,
37
- "embedContext": null,
38
- "phase": "behavioral",
39
- "provisional": false
52
+ "embed": null
40
53
  }
41
54
  }