Skip to content

Commit

Permalink
Merge pull request #105 from smswithoutborders/feature/grpc_api
Browse files Browse the repository at this point in the history
feat: add  GetEntityAccessTokenAndDecryptPayload, EncryptPayload and UpdateEntityToken functions
  • Loading branch information
PromiseFru authored Jun 17, 2024
2 parents 8ddd27e + 98502d6 commit b1bd41b
Show file tree
Hide file tree
Showing 10 changed files with 928 additions and 193 deletions.
234 changes: 233 additions & 1 deletion docs/grpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
- [Complete Authentication](#complete-authentication)
- [List an Entity's Stored Tokens](#list-an-entitys-stored-tokens)
- [Store an Entity's Token](#store-an-entitys-token)
- [Get Entity Access Token and Decrypt Payload](#get-entity-access-token-and-decrypt-payload)
- [Encrypt Payload](#encrypt-payload)
- [Update An Entity Token](#update-an-entitys-token)

## Download Protocol Buffer File

Expand Down Expand Up @@ -486,7 +489,7 @@ This method retrieves the stored tokens for a given entity.

```bash
grpcurl -plaintext \
-d '{"long_lived_token": "entity_id:long_lived_token"}' \
-d '{"long_lived_token": "long_lived_token"}' \
-proto protos/v1/vault.proto \
localhost:6000 vault.v1.Entity/ListEntityStoredTokens
```
Expand Down Expand Up @@ -603,3 +606,232 @@ localhost:6000 vault.v1.Entity/StoreEntityToken <payload.json
"success": true
}
```

#### Get Entity Access Token And Decrypt Payload

This function retrieves an entity's access token and decrypts the payload.

---

> `request` **GetEntityAccessTokenAndDecryptPayloadRequest**
> [!IMPORTANT]
>
> The table lists only the required fields for this step. Other fields will be
> ignored.
| Field | Type | Description |
| ------------------ | ------ | ------------------------------------------------------------------- |
| device_id | string | The unique identifier of the device used by the entity. |
| payload_ciphertext | string | The encrypted payload ciphertext that needs to be decrypted. |
| platform | string | The platform from which the token is being issued. (e.g., "gmail"). |

---

> `response` **GetEntityAccessTokenAndDecryptPayloadResponse**
> [!IMPORTANT]
>
> The table lists only the fields that are populated for this step. Other fields
> may be empty, omitted, or false.
| Field | Type | Description |
| ----------------- | ------ | -------------------------------------------------------------------------- |
| message | string | A response message from the server. |
| success | bool | Indicates if the operation was successful. |
| payload_plaintext | string | The decrypted payload plaintext. |
| token | string | The retrieved token associated with the entity for the specified platform. |

---

> `method` **GetEntityAccessTokenAndDecryptPayload**
> [!TIP]
>
> The examples below use
> [grpcurl](https://github.com/fullstorydev/grpcurl#grpcurl).
> [!NOTE]
>
> Here is what a successful response from the server looks like.
>
> The server would return a status code of `0 OK` if the API transaction goes
> through without any friction. Otherwise, it will return any other code out of
> the
> [17 codes supported by gRPC](https://grpc.github.io/grpc/core/md_doc_statuscodes.html).
---

**Sample request**

```bash
grpcurl -plaintext \
-d '{"device_id": "device_id", "payload_ciphertext": "encrypted_payload", "platform": "gmail"}' \
-proto protos/v1/vault.proto \
localhost:6000 vault.v1.Entity/GetEntityAccessTokenAndDecryptPayload
```

---

**Sample response**

```json
{
"message": "Successfully fetched tokens and decrypted payload",
"success": true,
"payload_plaintext": "Decrypted payload content",
"token": "retrieved_token"
}
```

---

#### Encrypt Payload

This function handles the encryption of payload content.

---

> `request` **EncryptPayloadRequest**
> [!IMPORTANT]
>
> The table lists only the required fields for this step. Other fields will be
> ignored.
| Field | Type | Description |
| ----------------- | ------ | ------------------------------------------------------- |
| device_id | string | The unique identifier of the device used by the entity. |
| payload_plaintext | string | The plaintext payload content to be encrypted. |

---

> `response` **EncryptPayloadResponse**
> [!IMPORTANT]
>
> The table lists only the fields that are populated for this step. Other fields
> may be empty, omitted, or false.
| Field | Type | Description |
| ------------------ | ------ | ------------------------------------------ |
| message | string | A response message from the server. |
| payload_ciphertext | string | The encrypted payload ciphertext. |
| success | bool | Indicates if the operation was successful. |

---

> `method` **EncryptPayload**
> [!TIP]
>
> The examples below use
> [grpcurl](https://github.com/fullstorydev/grpcurl#grpcurl).
> [!NOTE]
>
> Here is what a successful response from the server looks like.
>
> The server would return a status code of `0 OK` if the API transaction goes
> through without any friction. Otherwise, it will return any other code out of
> the
> [17 codes supported by gRPC](https://grpc.github.io/grpc/core/md_doc_statuscodes.html).
---

**Sample request**

```bash
grpcurl -plaintext \
-d '{"device_id": "device_id", "payload_plaintext": "plaintext_payload"}' \
-proto protos/v1/vault.proto \
localhost:6000 vault.v1.Entity/EncryptPayload
```

---

**Sample response**

```json
{
"message": "Successfully encrypted payload.",
"payload_ciphertext": "encrypted_payload",
"success": true
}
```

---

#### Update An Entity's Token

This function updates tokens associated with an entity.

---

> `request` **UpdateEntityTokenRequest**
> [!IMPORTANT]
>
> The table lists only the required fields for this step. Other fields will be
> ignored.
| Field | Type | Description |
| ------------------ | ------ | -------------------------------------------------------------------- |
| device_id | string | The unique identifier of the device used by the entity. |
| token | string | The new token to be updated for the entity. |
| platform | string | The platform from which the token is being updated. (e.g., "gmail"). |
| account_identifier | string | The identifier of the account associated with the token. |

---

> `response` **UpdateEntityTokenResponse**
> [!IMPORTANT]
>
> The table lists only the fields that are populated for this step. Other fields
> may be empty, omitted, or false.
| Field | Type | Description |
| ------- | ------ | ------------------------------------------ |
| message | string | A response message from the server. |
| success | bool | Indicates if the operation was successful. |

---

> `method` **UpdateEntityToken**
> [!TIP]
>
> The examples below use
> [grpcurl](https://github.com/fullstorydev/grpcurl#grpcurl).
> [!NOTE]
>
> Here is what a successful response from the server looks like.
>
> The server would return a status code of `0 OK` if the API transaction goes
> through without any friction. Otherwise, it will return any other code out of
> the
> [17 codes supported by gRPC](https://grpc.github.io/grpc/core/md_doc_statuscodes.html).
---

**Sample request**

```bash
grpcurl -plaintext \
-d '{"device_id": "device_id", "token": "new_token", "platform": "gmail", "account_identifier": "account_id"}' \
-proto protos/v1/vault.proto \
localhost:6000 vault.v1.Entity/UpdateEntityToken
```

---

**Sample response**

```json
{
"message": "Token updated successfully.",
"success": true
}
```
43 changes: 41 additions & 2 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,47 @@

## Password Security

Passwords are secured using HMAC-512. HMAC ([Hash-based Message Authentication Code](https://en.wikipedia.org/wiki/HMAC)) is a MAC defined in [RFC2104](http://www.ietf.org/rfc/rfc2104.txt) and [FIPS-198](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf) and constructed using a cryptographic hash algorithm.
Passwords are secured using HMAC-512. HMAC
([Hash-based Message Authentication Code](https://en.wikipedia.org/wiki/HMAC))
is a MAC defined in [RFC2104](http://www.ietf.org/rfc/rfc2104.txt) and
[FIPS-198](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf) and
constructed using a cryptographic hash algorithm.

## Data Security

Data is secured using AES-CBC. AES ([Advanced Encryption Standard](http://en.wikipedia.org/wiki/Advanced_Encryption_Standard)) is a symmetric block cipher standardized by [NIST](http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf) . It has a fixed data block size of 16 bytes. Its keys can be 128, 192, or 256 bits long.
Data is secured using AES-CBC. AES
([Advanced Encryption Standard](http://en.wikipedia.org/wiki/Advanced_Encryption_Standard))
is a symmetric block cipher standardized by
[NIST](http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf) . It has a
fixed data block size of 16 bytes. Its keys can be 128, 192, or 256 bits long.

## Cryptographic Methods Used in the Vault

These cryptographic methods are implemented in the [crypto.py](../src/crypto.py)
file within the vault.

### 1. AES Encryption

**AES (Advanced Encryption Standard)**:

- **Key Size**: 32 bytes
- **Mode of Operation**: AES.MODE_EAX
- **Usage**:
- Encrypts and decrypts data at rest in the vault.

### 2. HMAC Generation

**HMAC (Hash-based Message Authentication Code)**:

- **Algorithm**: SHA-512
- **Key Size**: 32 bytes
- **Usage**:
- Generates and verifies HMACs for unique values in the vault.

### 3. Fernet Encryption

**Fernet encryption**:

- **Key Size**: 32 bytes
- **Usage**:
- Encrypts and decrypts identity tokens used by the vault.
68 changes: 67 additions & 1 deletion protos/v1/vault.proto
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ message Token {
message StoreEntityTokenRequest {
// The long-lived token of the authenticated entity.
string long_lived_token = 1;
// The OAuth2 token to be stored.
// The OAuth2 token to be stored (JSON string).
string token = 2;
// The platform associated with the token.
string platform = 3;
Expand All @@ -106,6 +106,66 @@ message StoreEntityTokenResponse {
bool success = 2;
}

// Request message for getting entity access token and decrypting payload.
message GetEntityAccessTokenAndDecryptPayloadRequest {
// Device ID for identifying the requesting device.
string device_id = 1;
// Encrypted payload that needs to be decrypted.
string payload_ciphertext = 2;
// The platform associated with the token.
string platform = 3;
}

// Response message for getting entity access token and decrypting payload.
message GetEntityAccessTokenAndDecryptPayloadResponse {
// Entity access token (JSON string).
string token = 1;
// Decrypted plaintext payload.
string payload_plaintext = 2;
// A response message.
string message = 3;
// Indicates whether the operation was successful.
bool success = 4;
}

// Request message for encrypting payload.
message EncryptPayloadRequest {
// Device ID for identifying the requesting device.
string device_id = 1;
// Plaintext payload to be encrypted.
string payload_plaintext = 2;
}

// Response message for encrypting payload.
message EncryptPayloadResponse {
// Encrypted payload.
string payload_ciphertext = 1;
// A response message.
string message = 2;
// Indicates whether the operation was successful.
bool success = 3;
}

// Request message for updating an entity's token.
message UpdateEntityTokenRequest {
// Device ID for identifying the requesting device.
string device_id = 1;
// The OAuth2 token to be stored (JSON string).
string token = 2;
// The platform associated with the token.
string platform = 3;
// The identifier of the account associated with the token.
string account_identifier = 4;
}

// Response message for updating an entity's token.
message UpdateEntityTokenResponse {
// A response message.
string message = 1;
// Indicates whether the operation was successful.
bool success = 2;
}

// Service for managing entities.
service Entity {
// Creates an entity.
Expand All @@ -116,4 +176,10 @@ service Entity {
rpc ListEntityStoredTokens (ListEntityStoredTokenRequest) returns (ListEntityStoredTokenResponse);
// Stores a token for an entity.
rpc StoreEntityToken (StoreEntityTokenRequest) returns (StoreEntityTokenResponse);
// Get an entity's access token and decrypt payload.
rpc GetEntityAccessTokenAndDecryptPayload (GetEntityAccessTokenAndDecryptPayloadRequest) returns (GetEntityAccessTokenAndDecryptPayloadResponse);
// Encrypt payload.
rpc EncryptPayload (EncryptPayloadRequest) returns (EncryptPayloadResponse);
// Updates a token for an entity.
rpc UpdateEntityToken (UpdateEntityTokenRequest) returns (UpdateEntityTokenResponse);
}
Loading

0 comments on commit b1bd41b

Please sign in to comment.