Bootstrap & Credentials
Before a camera can run, two things have to be true: the engine needs its four
acquisition streams initialized, and its
UCSD credentials have to be encrypted at rest so the VAPIX request
builder can decrypt them at call time. Both happen at
bootstrap, and because both the automated refresher and the human-driven Admin portal need
to do exactly the same thing, the logic lives in one shared place: BootstrapService in
Alert.CA.Utility.
The one idea to hold on to
Bootstrap seeds orchestration state and encrypts credentials — and it's a single shared service so the security-sensitive parts can't drift between the two callers. Seeding the streams is deterministic setup:
public Dictionary<string, AcquisitionOrchestrationState> InitializeOrchestrationStates()
// seeds SINGLE, PANO, LEASED, TURBO
That dictionary is exactly what the engine's InitializeEntity signal writes onto the
CameraState entity during a redeploy —
so bootstrap and the engine agree on the shape of a camera's mode configuration by construction.
Credentials are encrypted, and only when they change
UCSD hands out root, operator, and viewer logins in plaintext. MapAndEncryptCredentialsAsync
turns each into an encrypted Credential via the Infrastructure encryption service:
Username = await _encryptionService.EncryptAsync(rootCred.Username),
Password = await _encryptionService.EncryptAsync(rootCred.Password)
And when re-bootstrapping an existing device, EncryptAcquisitionEntityFieldsAsync encrypts
the addresses and credentials but only the values that actually changed, flipping
IsEncrypted to true. That's the write-side partner to the read-side decrypt in the VAPIX
builder, and the same discipline the refresh loop's diff relies on.
Both Admin.API (portal onboarding) and CameraOperation (auto-refresh) bootstrap devices.
If either grew its own copy of the credential-mapping or stream-seeding logic, they'd drift —
and drift in credential encryption is a security bug, not a cosmetic one. That's the whole
reason BootstrapService lives in the shared Alert.CA.Utility library. New bootstrap
behavior goes there, not in a caller.
Wrapping up
Bootstrapping a camera means seeding its four orchestration streams (the same shape the engine
initializes on redeploy) and encrypting its UCSD credentials and addresses — re-encrypting only
what changed. It's a single shared service in Alert.CA.Utility precisely so the automated
refresher and the Admin portal can't diverge on security-critical logic.
Next, the other operational jobs that run around the engine: Jobs Around the Engine.