Credentials
Camera credentials are stored in the EdgeX Secret Store and referenced by MAC Address. All
devices by default are configured with credentials from DefaultSecretName
unless configured
as part of a group within AppCustom.CredentialsMap
.
Three things must be done in order to add an authenticated camera to EdgeX:
- Add device to EdgeX
- Manually or via auto-discovery
- Add Credentials
to Secret Store
- Manually or via utility scripts
- Map Credentials
to devices
- Manually or via utility scripts
- Configure as DefaultSecretName
Terminology / Definitions
- Secret: A generic map/object which is stored as multiple key/value pairs in the
Secret Store
under a specificSecret Name
key. - Credentials: A specific type of
Secret
which contains a mapping ofusername
,password
, and authenticationmode
. - Secret Store: The place EdgeX stores all
Secrets
- In secure mode this is
Vault
- In non-secure mode this is the configuration provider (typically
Consul
). They can be pre-configured viaconfiguration.yaml
'sWritable.InsecureSecrets
section. - Secret Name: The name/key of the
Secret
as they are stored in theSecret Store
. - CredentialsMap: (aka
AppCustom.CredentialsMap
) this contains the mappings betweenSecret Name
andMAC Address
. Each key in the map is aSecret Name
which points toCredentials
in theSecret Store
. The value for each key is a comma separated list ofMAC Addresses
which should use thoseCredentials
. - DefaultSecretName: The
Secret Name
which points to theCredentials
to use as the default for all devices which are not configured in theCredentialsMap
. - NoAuth: A special
Secret Name
that does not exist in theSecret Store
. It is pre-configured asCredentials
withAuthentication Mode
ofnone
.NoAuth
can be used most places where aSecret Name
is expected.
Camera credentials are stored in the EdgeX Secret Store, which is Vault in secure mode, and Consul in non-secure mode.
The term Secret Name
is often used to refer to the name of the credentials as they are stored in the Secret Store.
Credentials are then mapped to devices either using the DefaultSecretName
which applies to all devices by default,
or by configuring the AppCustom.CredentialsMap
which maps one or more MAC Addresses to the desired credentials.
Credentials Structure
Credentials
are SecretData
comprised of three fields:
- username
: the admin username for the camera
- password
: the admin password
- mode
: the type of Authentication to use
- usernametoken
: use a username and token based authentication
- digest
: use a digest based authentication
- both
: use both usernametoken
and digest
- none
: do not send any authentication headers
Add Credentials to Secret Store
Note
Credentials can be added and modified via utility scripts after the service is running
Non-Secure Mode
See here for the full guide.
Replace <secret-name>
with the name of the secret, <username>
with the username, <password>
with the password, and <mode>
with the auth mode.
Set SecretName to <device-name>
curl -X PUT --data "<secret-name>" \
"http://localhost:8500/v1/kv/edgex/v3/device-onvif-camera/Writable/InsecureSecrets/<secret-name>/SecretName"
Set username to <username>
curl -X PUT --data "<username>" \
"http://localhost:8500/v1/kv/edgex/v3/device-onvif-camera/Writable/InsecureSecrets/<secret-name>/SecretData/username"
Set password to <password>
curl -X PUT --data "<password>" \
"http://localhost:8500/v1/kv/edgex/v3/device-onvif-camera/Writable/InsecureSecrets/<secret-name>/SecretData/password"
Set auth mode to <auth-mode>
curl -X PUT --data "<auth-mode>" \
"http://localhost:8500/v1/kv/edgex/v3/device-onvif-camera/Writable/InsecureSecrets/<secret-name>/SecretData/mode"
Secure Mode
See here for the full guide.
Credentials can be added via EdgeX Secrets:
Replace <secret-name>
with the name of the secret, <username>
with the username, <password>
with the password, and <mode>
with the auth mode.
curl --location --request POST 'http://localhost:59984/api/v3/secret' \
--header 'Content-Type: application/json' \
--data-raw '
{
"apiVersion" : "v3",
"name": "<secret-name>",
"secretData":[
{
"key":"username",
"value":"<username>"
},
{
"key":"password",
"value":"<password>"
},
{
"key":"mode",
"value":"<mode>"
}
]
}'
Mapping Credentials to Devices
Note
Credential mappings can be set via utility scripts after the service is running
The device service supports three types of credential mapping. All three types can be used in conjunction with each other.
1 to All
- All devices are given the default credentials based onDefaultSecretName
1 to Many
- In theCredentialsMap
, one secret name can be assigned multiple MAC addresses1 to 1
- In theCredentialsMap
, assign each secret name 1 MAC Address
Manual Configuration
Note
Any key present in AppCustom.CredentialsMap
must also exist in the secret store!
# AppCustom.CredentialsMap is a map of SecretName -> Comma separated list of mac addresses.
# Every SecretName used here must also exist as a valid secret in the Secret Store.
#
# Note: Anything not defined here will be assigned the default credentials configured via `DefaultSecretName`.
#
# Example: (Single mapping for 1 mac address to 1 credential)
# credentials001 = "aa:bb:cc:dd:ee:ff"
#
# Example: (Multi mapping for 3 mac address to 1 shared credentials)
# credentials002 = "11:22:33:44:55:66,ff:ee:dd:cc:bb:aa,ab:12:12:34:34:56:56"
#
# These mappings can also be referred to as "groups". In the above case, the `credentials001` group has 1 MAC
# Address, and the `credentials002` group has 3 MAC Addresses.
#
# The special group 'NoAuth' defines mac addresses of cameras where no authentication is needed.
# The 'NoAuth' key does not exist in the SecretStore. It is not required to add MAC Addresses in here,
# however it avoids sending the default credentials to cameras which do not need it.
#
# IMPORTANT: A MAC Address may only exist in one credential group. If a MAC address is defined in more
# than one group, it is unpredictable which group the MAC will end up in! If you wish to change the group a MAC
# address belongs to, first remove it from its existing group, and then add it to the new one.
CredentialsMap:
NoAuth: ""
credentials001: "aa:bb:cc:dd:ee:ff"
credentials002: "11:22:33:44:55:66,ff:ee:dd:cc:bb:aa,ab:12:12:34:34:56:56"
Credential Lookup
Here is an in-depth look at the logic behind mapping Credentials
to Devices.
During Discovery
contain
MAC Address?} InNoAuthGroup{MAC Belongs
to NoAuth group?} AuthModeNone[Set AuthMode to 'none'] ApplyCreds[Apply Credentials] InSecretStore{Credentials exist
in SecretStore?} CreateClient[Create Onvif Client] GetDeviceInfo[Get Device Information] GetNetIfaces[Get Network Interfaces] CreateDevice(Create Device:
<Mfg>-<Model>-<EndpointRef>) CreateUnknownDevice(Create Device:
unknown_unknown_<EndpointRef>) %% -------- Graph Definitions -------- %% DiscoveredDevice --> ForAllMAC subgraph ForAllMAC[For all MAC Addresses in CredentialsMap] EndpointRefHasMAC end EndpointRefHasMAC -->|Yes| InNoAuthGroup EndpointRefHasMAC -- No Matches --> UseDefault InNoAuthGroup -->|Yes| AuthModeNone InNoAuthGroup -->|No| InSecretStore UseDefault --> InSecretStore AuthModeNone --> CreateClient InSecretStore -->|Yes| ApplyCreds InSecretStore -->|No| AuthModeNone ApplyCreds --> CreateClient CreateClient --> GetDeviceInfo GetDeviceInfo -->|Failed| CreateUnknownDevice GetDeviceInfo -->|Success| GetNetIfaces GetNetIfaces ----> CreateDevice
Connecting to Existing Devices
MAC Address?} ValidMAC{Is it a valid
MAC Address?} InMap{MAC exists in
CredentialsMap?} InNoAuth{MAC Belongs
to NoAuth group?} UseDefault[Use Default Credentials] InSecretStore{Credentials exist
in SecretStore?} AuthModeNone(Set AuthMode to 'none') ApplyCreds(Apply Credentials) CreateClient(Create Onvif Client) %% -------- Edge Definitions -------- %% ExistingDevice --> ContainsMAC ContainsMAC -->|Yes| ValidMAC ValidMAC -->|Yes| InMap ValidMAC -->|No| AuthModeNone InMap -->|Yes| InNoAuth InMap -->|No| AuthModeNone ContainsMAC -->|No| UseDefault InNoAuth -->|Yes| AuthModeNone InNoAuth -->|No| InSecretStore UseDefault --> InSecretStore InSecretStore -->|Yes| ApplyCreds InSecretStore -->|No| AuthModeNone AuthModeNone ----> CreateClient ApplyCreds ----> CreateClient