Storage Service
Use Modes
Remote
Type: REST Security: Client Authentication + Device Bound Tokens
The service can be used as a remote storage for mobile applications. In this case the storage verifies a device key against incoming tokens and accepts device registrations. For using this mode be aware that an additional protection by an mobile app protection framework is required to issue client certificates to establish an secure channel to the storage. An addtional fraud management can be docked by configuring the fraud management middleware.
Prerequisites
Each User must have the following preperations to use the backend:
- Valid Account created and validated over the Account Service
- Valid Client Certificate for mTLS
- RSA PSS Certificate for Signing Tokens and Decrypting Receipts
- RSA PSS Certificate to sign Credential Envelopes (Content Certificate)
Event
Type: NATS Security: API KEY
Direct
Type: REST Security: Standard JWK
API
Structure
TODO OPENAPI
Authorization Bearer
All credential routes are protected by a self signed token which must be created with the registered device key. The jwt must contain in the body:
- Nonce (initial nonce or from receipt)
- Subject (account id)
All nonces are just usable once and are invalid after receiving an receipt.
Example(signed with token from this repo):
eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiL3Rlc3QyL3RlbmFudF9zcGFjZS9BQkNEMTIzIl0sImV4cCI6MTcwMDUyNDU3OSwiaWF0IjoxNzAwNTIwOTc5LCJpc3MiOiJnaXRodWIuY29tL2xlc3RycmF0LWdvL2p3eCIsIm5vbmNlIjoiTlRVMU5RPT0iLCJzdWIiOiJBQkNEMTIzIn0.hOrqF6L6PaKsSOxlF6hUCBbDMJBhwXa7trqoW0cLw28CWv8bZxbWJccnfomkIin-ygJPsw4U7d8o4OHfhdHPETx7RGo2XBktIheERzivOORl3eDpqU7zfV9FTuU-U8dH9Tmx4HSpW9AS0c0SJjxzew4iwNC_UBy5KRBkgIwS7ZDNEDLpc4NTEwT9jfXwUUR6PopfeFr9kDtVEcmsXCxRVe8QQ_x_mFk_xtMoYzx-tKTLtXpH3KYKYmmAbcjkrfajcFi5w5Cai3OAO2ugfRZ6XTEev3_8SPMVgPq2Qoz2Ka3Cq26-7A7GzLrrLo5NAWe3urUMfxvtU9wsf_Wi535niw
Receipt
The receipt is returned in an JWE envelop adressed to the device key. After decrypting it, the receipt contains a nonce and nonce expired value for usage in the next call.
Usage
Register Device
Expects
Content-Type: application/json
Body: None
Method: GET
Example:
curl -H 'Authorization:Bearer eyJhbGciOiJFUzI1NiIsImp3ayI6eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiU2JTdlZNWGJDbjZnZWFMN1F1c3JtQk1nU29uRC1vclVkNUNUdGtLS1BmQSIsInkiOiJ1M2Fzd0tVbFVieGZjUXFLSUZJZGppdmZSbklEa3c2N0k4dUNGUjY4NmMwIn0sInR5cCI6IkpXVCJ9.eyJhdWQiOlsiL3RlbmFudF9zcGFjZS9BQkNEMTIzL3Rlc3QzIl0sImV4cCI6NTMwMjY0ODgxMywiaWF0IjoxNzAyNjUyNDEzLCJpc3MiOiJnaXRodWIuY29tL2xlc3RycmF0LWdvL2p3eCIsInN1YiI6IkFCQ0QxMjMifQ.VhLKC4ObpQuUq95aHIrhEAZXQS1lbvDEjAoExb3K4dfvjEOvWbPNc9ZE9119TpTMGmFtnJkFjIggh9hzbalTpA' https://.../ABCD123/device/registration/register
Returns
Content-Type: application/jose
Body: JWE encrypted by RSA_OAEP_256 and AES256_GCM
Example:
eyJjaXBoZXJ0ZXh0IjoiTS15bE9BcURqVFl5cjcxMElaaXRyQUtQRWVZeldsTlVXZTJpV25uU3hnck1ZMm5CMUJTbi16N1otdldLX1ctV1Jyanktb0hXZml2Tnd3TWVrTmRFN0VfV1dvR3FCYWk4WGlhVlZQdHp6cDRjTHJ5aU5GQjVWUE1VOVB4VlZQdUhlbGtfc2JKSVM4UUxreGk3VlEiLCJlbmNyeXB0ZWRfa2V5IjoiS2FQV0ZfeDlLV0c3aU51WlkzUUlaV2xlNUFkUFgyUFhSaTFDa3F1VkhLMWJZQ0c5VHZ3ZnBnIiwiaGVhZGVyIjp7ImFsZyI6IkVDREgtRVMrQTI1NktXIiwiZXBrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiX0JqX0gweURldGJ6bFo4NVQ5dXdOLW5UQWhQSWp6cjdybi1vRDB0Z1cyQSIsInkiOiJ5bjJ0T2JPUElSaGdETDQwMWdhTjFRTHFCVkliTzdSdUhTclFzbkR1NGJJIn19LCJpdiI6ImlMN3MyaWxqLVNWc2xROXoiLCJwcm90ZWN0ZWQiOiJleUpoYkdjaU9pSkZRMFJJTFVWVEswRXlOVFpMVnlJc0ltVnVZeUk2SWtFeU5UWkhRMDBpTENKbGNHc2lPbnNpWTNKMklqb2lVQzB5TlRZaUxDSnJkSGtpT2lKRlF5SXNJbmdpT2lKZlFtcGZTREI1UkdWMFlucHNXamcxVkRsMWQwNHRibFJCYUZCSmFucHlOM0p1TFc5RU1IUm5WekpCSWl3aWVTSTZJbmx1TW5SUFlrOVFTVkpvWjBSTU5EQXhaMkZPTVZGTWNVSldTV0pQTjFKMVNGTnlVWE51UkhVMFlra2lmWDAiLCJ0YWciOiJPV3VNbFp1SnBUbDk2VkR0RkM2RVBBIn0=
Create Session
Add Credential
This route receives a JWE message which contains the credential encrypted by the Users Content Certificate.
Expects
Content-Type: application/jose
Body: JWE encrypted by RSA_OAEP_256 and AES256_GCM
Method: PUT
Example:
Returns
Content-Type: application/jose
Body: JWE encrypted by RSA_OAEP_256 and AES256_GCM
Example:
Delete Credential Expects
Body: No Body Method: DELETE
Returns
Body: No Body
Get Credentials
Expects
Body: No Body Method: GET
Returns
Body:
Setup
1. Using makefilemake docker-compose-run
- Using docker compose directly
docker compose -f docker-compose.yml rm
docker compose -f docker-compose.yml --env-file=.env up --build --detach
Using Cassandra
Installation: https://cassandra.apache.org/_/quickstart.html
Python console: pip install -U cqlsh
Note: After bootstrapping the docker compose file, the initialize/insert container must be executed manually so long as no error occurs, because the cassandra DB needs a while to bootstrap.
Statements:
DESCRIBE keyspaces; //you should see tenant_space here select * from tenant_space.credentials;
Using Postman
Tokens+ PS256 Key Pairs can be created here: https://dinochiesa.github.io/jwt/
Sequence Diagram
title Cloud Storage
alt case Registration
App->Module:Initialize Cloud Storage
Module->Module:Create Keypair for Content Encryption(CE) and create Keypair for Device Binding (DB)
Module->Module: Create Key Storage
Module<->Key Storage: Store Key Pair
Module<->Key Storage: Extract Public Key
Module<->Key Storage: Create Self Signed JWT
Module->Cloud Storage: Register Account with Self Signed JWT
Cloud Storage->Cloud Storage: Insert in Db/Register Device Key
Cloud Storage->Module: Recovery Nonce + Nonce
Module->Module: Sign Recovery Nonce with Device Key to RJWT
Module->Module: Create QR Code (RJWT, CE)
Module->App: Please insert Password
App->Module:Password is...
Module->Module: Encrypt QR with KDF(PW) and base45 Encoding/Compression
Module->App: QR Code
end
alt Add Credential
App->Module: Store Credential
Module->Cloud Storage: Create Session
Cloud Storage->Module: Nonce
Module->Module: Sign JWT + Nonce with Device Key
Module->Module: Encrypt Credential with JWE
Module->Cloud Storage: Call Rest Api for Add Credential
Module->Module: Decrypt Response JWE
Module->App: Reponse
end
alt Delete Credential
App->Module: Delete Credential
Module->Cloud Storage: Create Session
Cloud Storage->Module: Nonce
Module->Module: Sign JWT + Nonce with Device Key
Module->Cloud Storage: Call Rest Api for Delete Credential
Module->Module: Decrypt Response JWE
Module->App: Response
end
alt Get Credentials
App->Module: Get Credentials
Module->Cloud Storage: Create Session
Cloud Storage->Module: Nonce
Module->Module: Sign JWT + Nonce with Device Key
Module->Cloud Storage: Call Rest Api for Get Credential
Module->Module: Decrypt Response JWE
Module->App: Credentials
end