BAS Sensitive People API - Usage
Note: This documentation is in the process of being migrated to
docs.api.bas.ac.uk. See this
snapshot in the interim.
Note: This API is unstable. Any part may change without warning without backwards compatibility.
This API follows the JSON API standard, unless stated otherwise.
Support
Limited, best effort, support is offered for those using this API to test integrating sensitive people information into
relevant workflows.
This API is currently designed for testing and provided without any availability, reliability or performance guarantees.
Contact the BAS Service Desk for support.
This API is designed to store and process sensitive information about individuals. Specifically this API provides
passport, date of birth and address details for current BAS Staff. This information is required for several workflows
which enable BAS to effectively and reliably comply with relevant legislation and/or regulations (such as providing
ship manifests to immigration control).
Specifically, this API provides sensitive information on a individuals:
- date of birth
- home address
- passport - number
- passport - country
- passport - issuing authority
- passport - issue date
- passport - expiry date
This information is encrypted and can only be decrypted by authorised applications. See the Encryption
section for more information. This API itself has no ability to decrypt real/production information.
Reasonable policies and technical measures are in place to ensure information in this API is held and transferred
securely. Where third parties are used to operate this API, we ensure they are used for a necessary task, with
measures are in place to ensure they are used appropriately and securely.
Applicable services used by this API are:
- Heroku - for storing data and hosting the API
- Sentry - for reporting API errors, which may include API responses containing encrypted data
This API is provided by the British Antarctic Survey, part of
UK Research and Innovation.
If you have any questions about how information is used by this API please contact the
BAS Service Desk in the first instance. If you do not receive a reply within a few days
please contact the BAS Freedom of Information Officer.
Security disclosures
Please contact the BAS Service Desk to disclose any security concerns with this API.
Contact us for instructions if you need to report any sensitive information.
Versioning policy
This API is versioned. An API version must be specified as a URL prefix (e.g. /v1/foo
).
The API change log describes changes within and between different versions.
Non-breaking changes, such as adding new options, may be made within a version. Breaking changes, such as renaming a
resource or changing a response structure, will be made as part of a new, stable, version. Major, non-breaking, changes
may also result in a new version, decided on a case by case basis.
Only the latest, stable, API version is supported (see the Support section for details). When a new version
is released previous versions are deprecated. See the Deprecation policy for how deprecated
versions are later removed.
Version |
Stable |
Notes |
Version 1 (v1 ) |
No |
Initially this version will be unstable, becoming stable later, this is an exception |
Testing version
For testing new features and changes, a non-stable, testing version of this API is available. This version should only
be used in development environments, when recommended by support. Separate client registrations are required to use the
testing version.
During initial development, all versions of this API use fake, but realistic information. In the future, stable versions
of the API will have access to real data. The testing version will always use fake data.
Fake data limitations
There are a number of general differences/limitations between fake and real data:
- the number of fake date items is arbitrary and are created or removed in bulk, the number of real data items is
based on the current number of staff, with items added and removed individually as staff join and leave
- attributes in fake data items don’t change, in real data individual attributes may change as necessary
See each resource for additional differences.
Deprecation policy
Features may be deprecated in this API as it evolves. This may include changes to options, methods, resources and API
versions. Usually an alternative feature will be available but in some cases a feature may be removed without one.
In either case, once deprecated it is expected the feature will be removed, with a timeline defined to ensure clients
have time to update their implementations to use preferred/supported alternatives where available.
Deprecated features will be referenced in this documentation and the API change log.
Base URL
The base URL for the testing version is: https://testing.api.bas.ac.uk/people-sensitive/testing
.
The base URL for the version 1 is: https://testing.api.bas.ac.uk/people-sensitive/v1
.
Note: This API is only available over HTTPS
.
Note: This API is currently available as a testing API.
Authentication and authorisation
Clients must be authorised to access to information held by this API using tokens with specific permissions for
different endpoints and/or resources.
Access is managed using Microsoft Azure’s Active Directory OAuth endpoints, which issues tokens to registered,
authorised, clients.
Clients request an access token from Azure, which will authenticate the client and encode
any assigned permissions as scopes within the token. This token is then included by the client
in requests to this API.
Note: Contact Support to request a new client registration.
Requesting an access token
Access tokens can be requested using the Client Credentials OAuth 2 code flow using these options:
Option |
Value |
Grant Type |
Client Credentials |
Client ID |
As per client registration |
Client Secret |
As per client registration |
Client Credentials Location |
In an authorization header using HTTP Basic Auth, not set in the request body |
For the testing version:
Option |
Value |
Access token URL |
https://login.microsoftonline.com/d14c529b-5558-4a80-93b6-7655681e55d6/oauth2/v2.0/token |
Scope(s) |
api://a56d0676-1551-45fc-8538-8b8a6fd4e2d2/.default |
For version 1:
Option |
Value |
Access token URL |
https://login.microsoftonline.com/b311db95-32ad-438f-a101-7ba061712a4e/oauth2/v2.0/token |
Scope(s) |
api://7f2a03aa-a9cf-48f1-bf27-6027cbeaad87/.default |
See this
documentation
for general information on requesting access tokens from Microsoft Azure.
Using an access token
After requesting an access token, include it in each request in an authorization
header as a bearer
token. E.g. authorization: bearer [token]
.
Content Types
This API supports the application/json
content type only, unless stated otherwise.
This API supports UTF-8
character encoding only, unless stated otherwise.
Request IDs
All requests will include a X-Request-ID
header to aid in debugging requests through different components.
If desired, a custom request ID can be specified by the client which will be used instead of, or in addition to a API
generated value.
Note: In some cases a client specified value will be ignored, ensure you do not rely on this value being returned.
Note: This header may include multiple values (multiple Request IDs) separated by a ,
with possible whitespace.
Resource model occurrence
Occurrence |
Condition |
Meaning |
0 |
N/A |
Attribute must not exist |
1 |
N/A |
Exactly one instance of an attribute must exist |
n |
Where n is an integer (e.g. 2) |
Exactly n instances of an attribute must exist (e.g. exactly two instances) |
0-1 |
N/A |
Up to one instance of an attribute may exist |
0-n |
Where n is n |
An attribute may exist any number of times |
0-n |
Where n is an integer (e.g. 2) |
n instances of an attribute may exist (e.g. up to two instances may exist) |
1-n |
Where n is n |
At least one instance of an attribute must exist, with no upper limit |
1-n |
Where n is an integer (e.g. 2) |
Between one and n instances of an attribute must exist |
n-N |
Where n is an integer (e.g. 2) and N is N |
At least n instances of an attribute must exist, with no upper limit |
n-N |
Where n and N are both integers (e.g. 2 and 4) |
Between n and N instances of an attribute must exist |
Data Types
String (data type)
String values are encoded as UTF-8.
Examples:
Date (data type)
Date values are encoded as ISO 8601 strings (i.e. YYYY-MM-DD
).
Examples:
Encrypted string (data type)
An encrypted string is an object with the following properties:
Property |
Data Type (Encrypted) |
Data Type (Clear Text) |
Occurrence |
Description |
data_type |
String |
String |
1 |
Data type of the value when decrypted |
variants |
N/A |
Array of Objects |
1-n |
Wrapper for a value encrypted using a particular format |
variants.*.format |
N/A |
String |
1 |
Encryption format used to encrypt the value |
variants.*.value |
String |
Various |
1 |
String representation of the value, encrypted using the given format |
See the Occurrence section for more information on these terms.
For example:
{
"data_type": "string",
"variants": [
{
"format": "plain_text_0",
"value": "conwat"
},
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQT-nDFJboe4gLuh8oe-dgk6Sc8PnxsJ7Hg5gcloo97JF4W8qKsik6-hvivuW0R-JelhnVFpxSsUaIJ8m-c2rdyjg=="
}
]
}
API methods that return large numbers of items will use pagination to split items into a number of pages based on the
JSON API specification.
Pages are a fixed size of 250 items per page, with the page
query string parameter selecting a page. Responses will
include links to navigate between pages. Where a link isn’t applicable (e.g. previous on the first page, null
its
value will be null
).
Pages start from 1
, where a page isn’t specified, the first page will be assumed. Where a page doesn’t exist a 404
Not Found error will be returned (e.g. if 4 pages exist but page 8 is requested, a 404 error will be returned).
For example:
{
"data": [],
"links": {
"first": "https://testing.api.bas.ac.uk/people-sensitive/v1/people-sensitive?page=1",
"last": "https://testing.api.bas.ac.uk/people-sensitive/v1/people-sensitive?page=4",
"next": "https://testing.api.bas.ac.uk/people-sensitive/v1/people-sensitive?page=3",
"prev": "https://testing.api.bas.ac.uk/people-sensitive/v1/people-sensitive?page=1",
"self": "https://testing.api.bas.ac.uk/people-sensitive/v1/people-sensitive?page=2"
}
}
Encryption
Encrypted values use one of these encryption formats:
clear_text_0
- unencrypted, used for non-sensitive information to allow decryption method to be verified
fernet_0x80
- Fernet encryption scheme, version 0x80
Encryption keys
During development, all encrypted information in this API is intended for testing, and encrypted using a test
encryption key. This key is considered insecure and will not, and must not, be used to encrypt any real data.
The test encryption key is: K7xW-dr3ReQN94B8uKcNf5caJOD0Xc3XZrVcG0WkCP4=
.
In production, all encrypted information must be considered real and treated with appropriate care. It is encrypted
using a production encryption key, which is considered secure and will not, and must not, be used to encrypt any test
data.
Contact Support to request the production encryption key.
Note: Currently the production encryption key is static, but may be dynamically issued in the future.
Test client
A minimal test client is available for this API, demonstrating how to retrieve the details of an individual and decrypt
attribute values for use.
The test client is a single file Python script, available in docs/scratch-client
. This script runs within a Docker
container for portability, but could be adapted not to.
Note: This test client is not intended to be used in production, it aims to provide a minimal, end-to-end example
of using this API to access and decrypt information.
Errors
Errors reported by this API follow the JSON API standard.
The id
property will vary with each error using a UUID.
Note: Some API errors are automatically captured by an error tracking service.
Resources
Person Sensitive
Sensitive information about a individual, designed to supplement a Person, which is a separate resource accessible
through the BAS People API, or in future, the BAS People Register.
This resource is intended to enrich a Person resource, avoiding duplication, but can be used as a standalone resource
when linked to another data source about individuals, such as Active Directory.
Username attribute
The username
attribute is taken from the EMAILID
field in UKSBS, with the domain removed (i.e. conwat@bas.ac.uk
becomes conwat
). Typically this field is populated with an individuals NUREM (NERC User Registration and Email
Management) username, maintained by NERC RTS, but this is not guaranteed.
This attribute is intended to find a user in this API from other identity sources, such as the NERC Active Directory.
The username
attribute is available in both clear-text and encrypted variants. This allows the decryption process
to be verified using a non-sensitive field. See the Encryption section for more information.
Passport attributes
It is not safe to assume attributes such as passport_number
will be same across all passports, including those issued
by the same authority.
For example:
- passport numbers may include letters in addition to numbers
- validity periods are not constant, UK passports could have up to 9 months over the usual 10 year period for example
Fake data limitations
- the username attribute in fake data does not represent typical username used in real data
- the passport issuing authority attribute in fake data will always be set to
-
which is not valid in real data
- the passport expiry date attribute in fake data will be greater than the typical expiry much more often than in
real data
Model
Person Sensitive summary model
Attribute |
Data Type (Encrypted) |
Data Type (Clear Text) |
Description |
Occurrence |
Unique |
Example Value (Clear Text) |
id |
N/A |
String |
Resource identifier |
1 |
Yes |
01D0FDHXH7MJXHAZECDPWP6JM2 |
type |
N/A |
String |
Type of resource |
1 |
Yes |
person-sensitive |
username |
N/A |
String |
NUREM identifier for an individual |
1 |
Yes |
conwat |
See the Occurrence section for more information on these terms.
For example:
{
"id": "01D0FDHXH7MJXHAZECDPWP6JM2",
"type": "person-sensitive",
"attributes": {
"username": "conwat"
}
}
Person Sensitive full model
Attribute |
Data Type (Encrypted) |
Data Type (Clear Text) |
Description |
Occurrence |
Unique |
Example Value (Clear Text) |
id |
N/A |
String |
Resource identifier |
1 |
Yes |
01D0FDHXH7MJXHAZECDPWP6JM2 |
type |
N/A |
String |
Type of resource |
1 |
No |
person-sensitive |
username |
Encrypted string |
String |
NUREM identifier for an individual |
1 |
No |
conwat |
date_of_birth |
Encrypted string |
Date |
Individuals date of birth |
1 |
No |
1992-12-22 |
passport_country |
Encrypted string |
String |
The country a passport is issued for |
1 |
No |
GB |
passport_number |
Encrypted string |
String |
The number assigned to a passport by the issuing authority |
1 |
No (Yes if combined with passport_issuing_authority ) |
123456789 |
passport_issuing_authority |
Encrypted string |
String |
The name of the authority that issued a passport |
1 |
No |
HMPO |
passport_date_issued |
Encrypted string |
Date |
The date after which a passport is valid |
1 |
No |
2011-01-23 |
passport_date_expires |
Encrypted string |
Date |
The date before which a passport is valid |
1 |
No |
2021-01-23 |
See the Occurrence section for more information on these terms.
For example:
{
"id": "01D0FDHXH7MJXHAZECDPWP6JM2",
"type": "person-sensitive",
"attributes": {
"username": {
"data_type": "string",
"variants": [
{
"format": "clear_text_0",
"value": "conwat"
},
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQT-nDFJboe4gLuh8oe-dgk6Sc8PnxsJ7Hg5gcloo97JF4W8qKsik6-hvivuW0R-JelhnVFpxSsUaIJ8m-c2rdyjg=="
}
]
},
"date_of_birth": {
"data_type": "date",
"variants": [
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQTpYxoByihfyL70GD9WHScIZtVXDujRInnAaim8gJ_BgENuN3eIPnRqAUPQzU-YIShTcmiMl9DlM5bSuCS3AOOZg=="
}
]
},
"passport_country": {
"data_type": "string",
"variants": [
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQTdjLtrhiacgXs6CLQA_bpV7l5wWjoS-heR7u4ONw7-ap2vRrSiF_kdD9OEE0nc4pNh_uNzCbk7tMWhfnsdb7AOA=="
}
]
},
"passport_number": {
"data_type": "string",
"variants": [
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQTbRwwBM-bPSnXWlFwBVmqS5jY7Z61r67d70XgDESC38NygWYpB-TfEDuVVOocwEt2EJ7aCjHELPIdFAcAc_CveQ=="
}
]
},
"passport_issuing_authority": {
"data_type": "string",
"variants": [
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQTYPmxWkw2_8bnbZ9qQ93sJj0WKZ3l8wrrXEJqU-aZJY6xRmp5ogrLoM778mQ8sir3yPxZCk075JX1ccDFZ6SuLg=="
}
]
},
"passport_date_issued": {
"data_type": "date",
"variants": [
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQT3s2OYQtoeGWXLt-wkgEftZnr44cRbZCM7AS0NwE6GlSEJOjSHgc_fh4ZQJHglxxrB10LzPyDdZliHe-K8Hfa2Q=="
}
]
},
"passport_date_expires": {
"data_type": "date",
"variants": [
{
"format": "fernet_0x80",
"value": "gAAAAABbZCQT-VUeWcAztFzlhcjESDx6I1QcimvfN40pDqxj2ejBH7oi2SIInuRiLcrHjDgxEISpDgFYPzxWUimDCPrHuFswdw=="
}
]
}
}
}