omgkit 2.12.0 → 2.15.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.
- package/README.md +97 -12
- package/package.json +2 -2
- package/plugin/agents/api-designer.md +5 -0
- package/plugin/agents/architect.md +8 -0
- package/plugin/agents/brainstormer.md +4 -0
- package/plugin/agents/cicd-manager.md +6 -0
- package/plugin/agents/code-reviewer.md +6 -0
- package/plugin/agents/copywriter.md +2 -0
- package/plugin/agents/data-engineer.md +255 -0
- package/plugin/agents/database-admin.md +10 -0
- package/plugin/agents/debugger.md +10 -0
- package/plugin/agents/devsecops.md +314 -0
- package/plugin/agents/docs-manager.md +4 -0
- package/plugin/agents/domain-decomposer.md +181 -0
- package/plugin/agents/embedded-systems.md +397 -0
- package/plugin/agents/fullstack-developer.md +12 -0
- package/plugin/agents/game-systems-designer.md +375 -0
- package/plugin/agents/git-manager.md +10 -0
- package/plugin/agents/journal-writer.md +2 -0
- package/plugin/agents/ml-engineer.md +284 -0
- package/plugin/agents/observability-engineer.md +353 -0
- package/plugin/agents/oracle.md +9 -0
- package/plugin/agents/performance-engineer.md +290 -0
- package/plugin/agents/pipeline-architect.md +6 -0
- package/plugin/agents/planner.md +12 -0
- package/plugin/agents/platform-engineer.md +325 -0
- package/plugin/agents/project-manager.md +3 -0
- package/plugin/agents/researcher.md +5 -0
- package/plugin/agents/scientific-computing.md +426 -0
- package/plugin/agents/scout.md +3 -0
- package/plugin/agents/security-auditor.md +7 -0
- package/plugin/agents/sprint-master.md +17 -0
- package/plugin/agents/tester.md +10 -0
- package/plugin/agents/ui-ux-designer.md +12 -0
- package/plugin/agents/vulnerability-scanner.md +6 -0
- package/plugin/commands/data/pipeline.md +47 -0
- package/plugin/commands/data/quality.md +49 -0
- package/plugin/commands/domain/analyze.md +34 -0
- package/plugin/commands/domain/map.md +41 -0
- package/plugin/commands/game/balance.md +56 -0
- package/plugin/commands/game/optimize.md +62 -0
- package/plugin/commands/iot/provision.md +58 -0
- package/plugin/commands/ml/evaluate.md +47 -0
- package/plugin/commands/ml/train.md +48 -0
- package/plugin/commands/perf/benchmark.md +54 -0
- package/plugin/commands/perf/profile.md +49 -0
- package/plugin/commands/platform/blueprint.md +56 -0
- package/plugin/commands/security/audit.md +54 -0
- package/plugin/commands/security/scan.md +55 -0
- package/plugin/commands/sre/dashboard.md +53 -0
- package/plugin/registry.yaml +711 -0
- package/plugin/skills/ai-ml/experiment-tracking/SKILL.md +338 -0
- package/plugin/skills/ai-ml/feature-stores/SKILL.md +340 -0
- package/plugin/skills/ai-ml/llm-ops/SKILL.md +454 -0
- package/plugin/skills/ai-ml/ml-pipelines/SKILL.md +390 -0
- package/plugin/skills/ai-ml/model-monitoring/SKILL.md +398 -0
- package/plugin/skills/ai-ml/model-serving/SKILL.md +386 -0
- package/plugin/skills/event-driven/cqrs-patterns/SKILL.md +348 -0
- package/plugin/skills/event-driven/event-sourcing/SKILL.md +334 -0
- package/plugin/skills/event-driven/kafka-deep/SKILL.md +252 -0
- package/plugin/skills/event-driven/saga-orchestration/SKILL.md +335 -0
- package/plugin/skills/event-driven/schema-registry/SKILL.md +328 -0
- package/plugin/skills/event-driven/stream-processing/SKILL.md +313 -0
- package/plugin/skills/game/game-audio/SKILL.md +446 -0
- package/plugin/skills/game/game-networking/SKILL.md +490 -0
- package/plugin/skills/game/godot-patterns/SKILL.md +413 -0
- package/plugin/skills/game/shader-programming/SKILL.md +492 -0
- package/plugin/skills/game/unity-patterns/SKILL.md +488 -0
- package/plugin/skills/iot/device-provisioning/SKILL.md +405 -0
- package/plugin/skills/iot/edge-computing/SKILL.md +369 -0
- package/plugin/skills/iot/industrial-protocols/SKILL.md +438 -0
- package/plugin/skills/iot/mqtt-deep/SKILL.md +418 -0
- package/plugin/skills/iot/ota-updates/SKILL.md +426 -0
- package/plugin/skills/microservices/api-gateway-patterns/SKILL.md +201 -0
- package/plugin/skills/microservices/circuit-breaker-patterns/SKILL.md +246 -0
- package/plugin/skills/microservices/contract-testing/SKILL.md +284 -0
- package/plugin/skills/microservices/distributed-tracing/SKILL.md +246 -0
- package/plugin/skills/microservices/service-discovery/SKILL.md +304 -0
- package/plugin/skills/microservices/service-mesh/SKILL.md +181 -0
- package/plugin/skills/mobile-advanced/mobile-ci-cd/SKILL.md +407 -0
- package/plugin/skills/mobile-advanced/mobile-security/SKILL.md +403 -0
- package/plugin/skills/mobile-advanced/offline-first/SKILL.md +473 -0
- package/plugin/skills/mobile-advanced/push-notifications/SKILL.md +494 -0
- package/plugin/skills/mobile-advanced/react-native-deep/SKILL.md +374 -0
- package/plugin/skills/simulation/numerical-methods/SKILL.md +434 -0
- package/plugin/skills/simulation/parallel-computing/SKILL.md +382 -0
- package/plugin/skills/simulation/physics-engines/SKILL.md +377 -0
- package/plugin/skills/simulation/validation-verification/SKILL.md +479 -0
- package/plugin/skills/simulation/visualization-scientific/SKILL.md +365 -0
- package/plugin/templates/autonomous/archetypes/event-driven-app.yaml +460 -0
- package/plugin/templates/autonomous/archetypes/microservices-app.yaml +431 -0
- package/plugin/templates/autonomous/state-schema.yaml +1 -1
- package/plugin/workflows/ai-engineering/agent-development.md +3 -3
- package/plugin/workflows/ai-engineering/fine-tuning.md +3 -3
- package/plugin/workflows/ai-engineering/model-evaluation.md +3 -3
- package/plugin/workflows/ai-engineering/prompt-engineering.md +2 -2
- package/plugin/workflows/ai-engineering/rag-development.md +4 -4
- package/plugin/workflows/ai-ml/data-pipeline.md +188 -0
- package/plugin/workflows/ai-ml/experiment-cycle.md +203 -0
- package/plugin/workflows/ai-ml/feature-engineering.md +208 -0
- package/plugin/workflows/ai-ml/model-deployment.md +199 -0
- package/plugin/workflows/ai-ml/monitoring-setup.md +227 -0
- package/plugin/workflows/api/api-design.md +1 -1
- package/plugin/workflows/api/api-testing.md +2 -2
- package/plugin/workflows/content/technical-docs.md +1 -1
- package/plugin/workflows/database/migration.md +1 -1
- package/plugin/workflows/database/optimization.md +1 -1
- package/plugin/workflows/database/schema-design.md +3 -3
- package/plugin/workflows/development/bug-fix.md +3 -3
- package/plugin/workflows/development/code-review.md +2 -1
- package/plugin/workflows/development/feature.md +3 -3
- package/plugin/workflows/development/refactor.md +2 -2
- package/plugin/workflows/event-driven/consumer-groups.md +190 -0
- package/plugin/workflows/event-driven/event-storming.md +172 -0
- package/plugin/workflows/event-driven/replay-testing.md +186 -0
- package/plugin/workflows/event-driven/saga-implementation.md +206 -0
- package/plugin/workflows/event-driven/schema-evolution.md +173 -0
- package/plugin/workflows/fullstack/authentication.md +4 -4
- package/plugin/workflows/fullstack/full-feature.md +4 -4
- package/plugin/workflows/game-dev/content-pipeline.md +218 -0
- package/plugin/workflows/game-dev/platform-submission.md +263 -0
- package/plugin/workflows/game-dev/playtesting.md +237 -0
- package/plugin/workflows/game-dev/prototype-to-production.md +205 -0
- package/plugin/workflows/microservices/contract-first.md +151 -0
- package/plugin/workflows/microservices/distributed-tracing.md +166 -0
- package/plugin/workflows/microservices/domain-decomposition.md +123 -0
- package/plugin/workflows/microservices/integration-testing.md +149 -0
- package/plugin/workflows/microservices/service-mesh-setup.md +153 -0
- package/plugin/workflows/microservices/service-scaffolding.md +151 -0
- package/plugin/workflows/omega/1000x-innovation.md +2 -2
- package/plugin/workflows/omega/100x-architecture.md +2 -2
- package/plugin/workflows/omega/10x-improvement.md +2 -2
- package/plugin/workflows/quality/performance-optimization.md +2 -2
- package/plugin/workflows/research/best-practices.md +1 -1
- package/plugin/workflows/research/technology-research.md +1 -1
- package/plugin/workflows/security/penetration-testing.md +3 -3
- package/plugin/workflows/security/security-audit.md +3 -3
- package/plugin/workflows/sprint/sprint-execution.md +2 -2
- package/plugin/workflows/sprint/sprint-retrospective.md +1 -1
- package/plugin/workflows/sprint/sprint-setup.md +1 -1
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
# Device Provisioning
|
|
2
|
+
|
|
3
|
+
Secure device onboarding, certificate management, fleet provisioning, and zero-touch deployment.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Device provisioning securely onboards IoT devices to a fleet, establishing identity, credentials, and configuration.
|
|
8
|
+
|
|
9
|
+
## Core Concepts
|
|
10
|
+
|
|
11
|
+
### Provisioning Methods
|
|
12
|
+
- **Pre-provisioning**: Credentials loaded at manufacture
|
|
13
|
+
- **Just-in-time**: Credentials issued on first connection
|
|
14
|
+
- **Self-provisioning**: Device generates own credentials
|
|
15
|
+
- **Fleet provisioning**: Template-based bulk provisioning
|
|
16
|
+
|
|
17
|
+
### Security Requirements
|
|
18
|
+
- Unique device identity
|
|
19
|
+
- Secure credential storage
|
|
20
|
+
- Certificate rotation
|
|
21
|
+
- Revocation capability
|
|
22
|
+
|
|
23
|
+
## AWS IoT Device Provisioning
|
|
24
|
+
|
|
25
|
+
### Fleet Provisioning Template
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"Parameters": {
|
|
29
|
+
"SerialNumber": { "Type": "String" },
|
|
30
|
+
"DeviceType": { "Type": "String" },
|
|
31
|
+
"FirmwareVersion": { "Type": "String" }
|
|
32
|
+
},
|
|
33
|
+
"Resources": {
|
|
34
|
+
"certificate": {
|
|
35
|
+
"Type": "AWS::IoT::Certificate",
|
|
36
|
+
"Properties": {
|
|
37
|
+
"CertificateId": { "Ref": "AWS::IoT::Certificate::Id" },
|
|
38
|
+
"Status": "Active"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"policy": {
|
|
42
|
+
"Type": "AWS::IoT::Policy",
|
|
43
|
+
"Properties": {
|
|
44
|
+
"PolicyDocument": {
|
|
45
|
+
"Version": "2012-10-17",
|
|
46
|
+
"Statement": [
|
|
47
|
+
{
|
|
48
|
+
"Effect": "Allow",
|
|
49
|
+
"Action": ["iot:Connect"],
|
|
50
|
+
"Resource": {
|
|
51
|
+
"Fn::Join": ["", [
|
|
52
|
+
"arn:aws:iot:",
|
|
53
|
+
{ "Ref": "AWS::Region" },
|
|
54
|
+
":",
|
|
55
|
+
{ "Ref": "AWS::AccountId" },
|
|
56
|
+
":client/${iot:Connection.Thing.ThingName}"
|
|
57
|
+
]]
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"Effect": "Allow",
|
|
62
|
+
"Action": ["iot:Publish", "iot:Receive"],
|
|
63
|
+
"Resource": {
|
|
64
|
+
"Fn::Join": ["", [
|
|
65
|
+
"arn:aws:iot:",
|
|
66
|
+
{ "Ref": "AWS::Region" },
|
|
67
|
+
":",
|
|
68
|
+
{ "Ref": "AWS::AccountId" },
|
|
69
|
+
":topic/devices/${iot:Connection.Thing.ThingName}/*"
|
|
70
|
+
]]
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"Effect": "Allow",
|
|
75
|
+
"Action": ["iot:Subscribe"],
|
|
76
|
+
"Resource": {
|
|
77
|
+
"Fn::Join": ["", [
|
|
78
|
+
"arn:aws:iot:",
|
|
79
|
+
{ "Ref": "AWS::Region" },
|
|
80
|
+
":",
|
|
81
|
+
{ "Ref": "AWS::AccountId" },
|
|
82
|
+
":topicfilter/devices/${iot:Connection.Thing.ThingName}/*"
|
|
83
|
+
]]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"thing": {
|
|
91
|
+
"Type": "AWS::IoT::Thing",
|
|
92
|
+
"Properties": {
|
|
93
|
+
"ThingName": { "Fn::Join": ["-", ["device", { "Ref": "SerialNumber" }]] },
|
|
94
|
+
"AttributePayload": {
|
|
95
|
+
"serialNumber": { "Ref": "SerialNumber" },
|
|
96
|
+
"deviceType": { "Ref": "DeviceType" },
|
|
97
|
+
"firmwareVersion": { "Ref": "FirmwareVersion" }
|
|
98
|
+
},
|
|
99
|
+
"ThingGroups": [{ "Ref": "DeviceType" }]
|
|
100
|
+
},
|
|
101
|
+
"OverrideSettings": {
|
|
102
|
+
"AttributePayload": "MERGE",
|
|
103
|
+
"ThingGroups": "DO_NOTHING"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Device-Side Provisioning (ESP32)
|
|
111
|
+
```cpp
|
|
112
|
+
#include <WiFiClientSecure.h>
|
|
113
|
+
#include <MQTTClient.h>
|
|
114
|
+
#include <ArduinoJson.h>
|
|
115
|
+
#include "Preferences.h"
|
|
116
|
+
|
|
117
|
+
// Claim certificate (embedded at manufacture)
|
|
118
|
+
const char* CLAIM_CERT = "-----BEGIN CERTIFICATE-----\n...";
|
|
119
|
+
const char* CLAIM_KEY = "-----BEGIN RSA PRIVATE KEY-----\n...";
|
|
120
|
+
const char* ROOT_CA = "-----BEGIN CERTIFICATE-----\n...";
|
|
121
|
+
|
|
122
|
+
Preferences prefs;
|
|
123
|
+
WiFiClientSecure net;
|
|
124
|
+
MQTTClient mqtt(4096);
|
|
125
|
+
|
|
126
|
+
struct DeviceCredentials {
|
|
127
|
+
String certificatePem;
|
|
128
|
+
String privateKey;
|
|
129
|
+
String thingName;
|
|
130
|
+
bool provisioned;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
DeviceCredentials credentials;
|
|
134
|
+
|
|
135
|
+
void loadCredentials() {
|
|
136
|
+
prefs.begin("credentials", true);
|
|
137
|
+
credentials.provisioned = prefs.getBool("provisioned", false);
|
|
138
|
+
if (credentials.provisioned) {
|
|
139
|
+
credentials.certificatePem = prefs.getString("cert");
|
|
140
|
+
credentials.privateKey = prefs.getString("key");
|
|
141
|
+
credentials.thingName = prefs.getString("thing");
|
|
142
|
+
}
|
|
143
|
+
prefs.end();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
void saveCredentials() {
|
|
147
|
+
prefs.begin("credentials", false);
|
|
148
|
+
prefs.putBool("provisioned", true);
|
|
149
|
+
prefs.putString("cert", credentials.certificatePem);
|
|
150
|
+
prefs.putString("key", credentials.privateKey);
|
|
151
|
+
prefs.putString("thing", credentials.thingName);
|
|
152
|
+
prefs.end();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
void provisionDevice() {
|
|
156
|
+
// Connect with claim certificate
|
|
157
|
+
net.setCACert(ROOT_CA);
|
|
158
|
+
net.setCertificate(CLAIM_CERT);
|
|
159
|
+
net.setPrivateKey(CLAIM_KEY);
|
|
160
|
+
|
|
161
|
+
mqtt.begin("xxx.iot.region.amazonaws.com", 8883, net);
|
|
162
|
+
|
|
163
|
+
if (!mqtt.connect("provisioning-client")) {
|
|
164
|
+
Serial.println("Provisioning connection failed");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Subscribe to provisioning topics
|
|
169
|
+
mqtt.subscribe("$aws/provisioning-templates/MyTemplate/provision/json/accepted");
|
|
170
|
+
mqtt.subscribe("$aws/provisioning-templates/MyTemplate/provision/json/rejected");
|
|
171
|
+
|
|
172
|
+
// Create provisioning request
|
|
173
|
+
StaticJsonDocument<256> doc;
|
|
174
|
+
doc["serialNumber"] = getChipId();
|
|
175
|
+
doc["deviceType"] = "sensor-v2";
|
|
176
|
+
doc["firmwareVersion"] = FIRMWARE_VERSION;
|
|
177
|
+
|
|
178
|
+
String payload;
|
|
179
|
+
serializeJson(doc, payload);
|
|
180
|
+
|
|
181
|
+
mqtt.publish("$aws/provisioning-templates/MyTemplate/provision/json", payload);
|
|
182
|
+
|
|
183
|
+
// Wait for response
|
|
184
|
+
unsigned long start = millis();
|
|
185
|
+
while (millis() - start < 30000) {
|
|
186
|
+
mqtt.loop();
|
|
187
|
+
|
|
188
|
+
if (credentials.provisioned) {
|
|
189
|
+
Serial.println("Provisioning successful");
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
delay(100);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
mqtt.disconnect();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
void handleProvisioningResponse(String& topic, String& payload) {
|
|
200
|
+
if (topic.endsWith("/accepted")) {
|
|
201
|
+
StaticJsonDocument<2048> doc;
|
|
202
|
+
deserializeJson(doc, payload);
|
|
203
|
+
|
|
204
|
+
credentials.certificatePem = doc["certificatePem"].as<String>();
|
|
205
|
+
credentials.privateKey = doc["privateKeyPem"].as<String>();
|
|
206
|
+
credentials.thingName = doc["thingName"].as<String>();
|
|
207
|
+
credentials.provisioned = true;
|
|
208
|
+
|
|
209
|
+
saveCredentials();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
void setup() {
|
|
214
|
+
Serial.begin(115200);
|
|
215
|
+
connectWiFi();
|
|
216
|
+
|
|
217
|
+
loadCredentials();
|
|
218
|
+
|
|
219
|
+
if (!credentials.provisioned) {
|
|
220
|
+
Serial.println("Starting provisioning...");
|
|
221
|
+
provisionDevice();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (credentials.provisioned) {
|
|
225
|
+
// Connect with device certificate
|
|
226
|
+
connectWithDeviceCert();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Certificate Management
|
|
232
|
+
|
|
233
|
+
### Certificate Rotation
|
|
234
|
+
```python
|
|
235
|
+
from datetime import datetime, timedelta
|
|
236
|
+
from cryptography import x509
|
|
237
|
+
from cryptography.x509.oid import NameOID
|
|
238
|
+
from cryptography.hazmat.primitives import hashes
|
|
239
|
+
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
240
|
+
from cryptography.hazmat.primitives import serialization
|
|
241
|
+
|
|
242
|
+
class CertificateManager:
|
|
243
|
+
def __init__(self, ca_cert_path: str, ca_key_path: str):
|
|
244
|
+
with open(ca_cert_path, 'rb') as f:
|
|
245
|
+
self.ca_cert = x509.load_pem_x509_certificate(f.read())
|
|
246
|
+
with open(ca_key_path, 'rb') as f:
|
|
247
|
+
self.ca_key = serialization.load_pem_private_key(f.read(), password=None)
|
|
248
|
+
|
|
249
|
+
def issue_certificate(
|
|
250
|
+
self,
|
|
251
|
+
device_id: str,
|
|
252
|
+
validity_days: int = 365
|
|
253
|
+
) -> tuple:
|
|
254
|
+
"""Issue a new device certificate"""
|
|
255
|
+
# Generate key pair
|
|
256
|
+
private_key = rsa.generate_private_key(
|
|
257
|
+
public_exponent=65537,
|
|
258
|
+
key_size=2048
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
# Create certificate
|
|
262
|
+
subject = x509.Name([
|
|
263
|
+
x509.NameAttribute(NameOID.COMMON_NAME, device_id),
|
|
264
|
+
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "IoT Fleet")
|
|
265
|
+
])
|
|
266
|
+
|
|
267
|
+
cert = (
|
|
268
|
+
x509.CertificateBuilder()
|
|
269
|
+
.subject_name(subject)
|
|
270
|
+
.issuer_name(self.ca_cert.subject)
|
|
271
|
+
.public_key(private_key.public_key())
|
|
272
|
+
.serial_number(x509.random_serial_number())
|
|
273
|
+
.not_valid_before(datetime.utcnow())
|
|
274
|
+
.not_valid_after(datetime.utcnow() + timedelta(days=validity_days))
|
|
275
|
+
.add_extension(
|
|
276
|
+
x509.BasicConstraints(ca=False, path_length=None),
|
|
277
|
+
critical=True
|
|
278
|
+
)
|
|
279
|
+
.sign(self.ca_key, hashes.SHA256())
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
# Serialize
|
|
283
|
+
cert_pem = cert.public_bytes(serialization.Encoding.PEM)
|
|
284
|
+
key_pem = private_key.private_bytes(
|
|
285
|
+
encoding=serialization.Encoding.PEM,
|
|
286
|
+
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
287
|
+
encryption_algorithm=serialization.NoEncryption()
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
return cert_pem, key_pem
|
|
291
|
+
|
|
292
|
+
def should_rotate(self, cert_pem: bytes, threshold_days: int = 30) -> bool:
|
|
293
|
+
"""Check if certificate needs rotation"""
|
|
294
|
+
cert = x509.load_pem_x509_certificate(cert_pem)
|
|
295
|
+
days_until_expiry = (cert.not_valid_after - datetime.utcnow()).days
|
|
296
|
+
return days_until_expiry < threshold_days
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Provisioning Service
|
|
300
|
+
|
|
301
|
+
### Backend API
|
|
302
|
+
```python
|
|
303
|
+
from fastapi import FastAPI, HTTPException
|
|
304
|
+
from pydantic import BaseModel
|
|
305
|
+
import boto3
|
|
306
|
+
|
|
307
|
+
app = FastAPI()
|
|
308
|
+
iot = boto3.client('iot')
|
|
309
|
+
|
|
310
|
+
class ProvisioningRequest(BaseModel):
|
|
311
|
+
serial_number: str
|
|
312
|
+
device_type: str
|
|
313
|
+
firmware_version: str
|
|
314
|
+
claim_token: str
|
|
315
|
+
|
|
316
|
+
class ProvisioningResponse(BaseModel):
|
|
317
|
+
thing_name: str
|
|
318
|
+
certificate_pem: str
|
|
319
|
+
private_key: str
|
|
320
|
+
root_ca: str
|
|
321
|
+
endpoint: str
|
|
322
|
+
|
|
323
|
+
@app.post("/provision", response_model=ProvisioningResponse)
|
|
324
|
+
async def provision_device(request: ProvisioningRequest):
|
|
325
|
+
# Validate claim token
|
|
326
|
+
if not validate_claim_token(request.claim_token, request.serial_number):
|
|
327
|
+
raise HTTPException(status_code=401, detail="Invalid claim token")
|
|
328
|
+
|
|
329
|
+
# Check if device already provisioned
|
|
330
|
+
thing_name = f"device-{request.serial_number}"
|
|
331
|
+
try:
|
|
332
|
+
iot.describe_thing(thingName=thing_name)
|
|
333
|
+
raise HTTPException(status_code=409, detail="Device already provisioned")
|
|
334
|
+
except iot.exceptions.ResourceNotFoundException:
|
|
335
|
+
pass
|
|
336
|
+
|
|
337
|
+
# Create certificate
|
|
338
|
+
cert_response = iot.create_keys_and_certificate(setAsActive=True)
|
|
339
|
+
|
|
340
|
+
# Create thing
|
|
341
|
+
iot.create_thing(
|
|
342
|
+
thingName=thing_name,
|
|
343
|
+
thingTypeName=request.device_type,
|
|
344
|
+
attributePayload={
|
|
345
|
+
'attributes': {
|
|
346
|
+
'serialNumber': request.serial_number,
|
|
347
|
+
'firmwareVersion': request.firmware_version
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
# Attach certificate to thing
|
|
353
|
+
iot.attach_thing_principal(
|
|
354
|
+
thingName=thing_name,
|
|
355
|
+
principal=cert_response['certificateArn']
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
# Attach policy
|
|
359
|
+
iot.attach_policy(
|
|
360
|
+
policyName=f"{request.device_type}-policy",
|
|
361
|
+
target=cert_response['certificateArn']
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
# Get endpoint
|
|
365
|
+
endpoint = iot.describe_endpoint(endpointType='iot:Data-ATS')
|
|
366
|
+
|
|
367
|
+
return ProvisioningResponse(
|
|
368
|
+
thing_name=thing_name,
|
|
369
|
+
certificate_pem=cert_response['certificatePem'],
|
|
370
|
+
private_key=cert_response['keyPair']['PrivateKey'],
|
|
371
|
+
root_ca=get_root_ca(),
|
|
372
|
+
endpoint=endpoint['endpointAddress']
|
|
373
|
+
)
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Best Practices
|
|
377
|
+
|
|
378
|
+
1. **Unique Identity**: Each device has unique credentials
|
|
379
|
+
2. **Secure Storage**: Use hardware security modules
|
|
380
|
+
3. **Certificate Rotation**: Auto-rotate before expiry
|
|
381
|
+
4. **Audit Trail**: Log all provisioning events
|
|
382
|
+
5. **Revocation Support**: Ability to revoke compromised devices
|
|
383
|
+
|
|
384
|
+
## Anti-Patterns
|
|
385
|
+
|
|
386
|
+
- Shared credentials across devices
|
|
387
|
+
- Hardcoded credentials
|
|
388
|
+
- No certificate expiration
|
|
389
|
+
- Missing revocation mechanism
|
|
390
|
+
- Unencrypted credential storage
|
|
391
|
+
|
|
392
|
+
## When to Use
|
|
393
|
+
|
|
394
|
+
- Fleet management at scale
|
|
395
|
+
- Security-critical deployments
|
|
396
|
+
- Regulatory compliance requirements
|
|
397
|
+
- Zero-touch deployment needs
|
|
398
|
+
- Dynamic fleet scaling
|
|
399
|
+
|
|
400
|
+
## When NOT to Use
|
|
401
|
+
|
|
402
|
+
- Small fixed fleet
|
|
403
|
+
- Dev/prototype phase
|
|
404
|
+
- No security requirements
|
|
405
|
+
- Manual deployment acceptable
|