Juniper Connect uses a scheme for primary keys which is designed to achieve the following goals:
IDs should be unique (even across environments)
IDs should be secure (not guessable)
IDs should be sequential (for performance reasons)
It should be easy to tell what resource an ID refers to
It should be easy to tell what environment an ID came from
It should enable polymorphic relationships
It should help to prevent human error
Remember the human
The anatomy of a Juniper Connect ID is driven by our desire to design APIs for the human developers who need to integrate them. Computers generally don’t care about what an ID looks like, as long as it’s unique. The humans that develop using those IDs do care very much though, which is why we put a lot of effort into the developer experience of our API.
Structure
Rather than using a simple secure random string, Juniper Connect IDs are prefixed with
the resource type,
the environment,
the hexadecimal timestamp of when the resource was created
This makes it easy to identify the type of resource and the environment it belongs to, helps improve database performance, and is also secure and unguessable.
Examples
stu_live_65521b2d5f3b2a48b2dd9bc1 - A student in the production environment
org_stg_65521b2dffb47adc312e1a2d - An organisation in the staging environment
Polymorphic Relationships
A key structure that allows us to infer object types is especially relevant when designing APIs with backwards compatibility in mind.
Preventing human error
There are other less obvious benefits of prefixing, one being the ease of working with IDs when you can infer their type from the first few characters. For example, when filtering sensitive information from emails or log files, we can flag and block messages that contain a Juniper Connect live secret API key, which starts with sk_live_.