Skip to main content

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.

Gotcha: one place on purpose — don't reimplement it

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.