## Purpose of this document
Provide the necessary technical information for the engineering team to deliver the Prism SaaS solution MVP.
## Decisions
### `prism-node` service is deployed in the in-memory mode
Expected outcome:
- deployment simplification
- environment cost optimization
- `prism-agent` configuration is simple
Constraints:
- Prism DID is not published to the blockchain
- absence of interoperability with other SSI systems
Mitigation:
- Cardano stack can be added later
### `prism-node` service is shared among all `prism-agent` instances
Expected outcome:
- deployment simplification
- cost optimization
- Cardano Wallet is not a part of SaaS
- `prism-agent` configuration is simple
Constraints:
- `prism-node` is a single point of failure
Mitigation:
- mitigate the SPOF later
- switch to Demeter Cadrano infrastructure
### `prism-agent` service uses Postgresql as a Secrets Store
Expected outcome:
- deployment simplification (the Vault is not needed)
- cost optimization
Constraints:
- the key materials are stored in not secure location
Mitigation:
- Switch to the Vault service after multi-tenancy implementation
### `prism-mediator` and mediator database are shared among all `prism-agent` instances
Expected outcome:
- deployment simplification
- cost optimization
- `prism-agent` configuration is simple
Constraints:
- `prism-mediator` is a SPOF
Mitigation:
- mitigate the SPOF after SaaS MVP
### `provisioning-backend` is implemented using TypeScript + Node.js
Expected outcome:
- engineers with TS experience implement provisioning backend
- provisioning backend is simple and maintainable
### Manage App and Enterprise Services are shared among all the `prism-agent` instances
Javier says that it's possible and the work to implement it is in progress.
Expected outcome:
- deployment simplification
- cost optimization
Constraints:
- Enterprise service is SPOF
## Architecture questions to figure out
### How to use the Cardano Wallet in SaaS offering?
//out of scope for now
### What Identity and Access Management (IAM) system should be used?
// the Keycloak, the Vault, something other
### How to configure the cluster management for the SaaS solution
There are the following options:
#### ??? ArgoCD + Postgresql + ArgoCD REST API
// Platform Engineering task - with @David Poltorak.
## New Components for the SaaS MVP
### Provisioning-backend
Purpose:
- orchestrate the resources of the SaaS environment
- communicate with the underlying infrastructure systems
- expose the REST API for resource orchestration
### IAM system
Purpose:
- provide the authentication method for the SaaS
- manage the users (create, activate, deactivate, update, get information)
## Admin UI (optional for MVP)
Purpose:
- observe the status of the SaaS environment
- manage the SaaS environment
ArgoCD + Grafana + Prometheus can be used so far
## Deployment Diagram
This diagram is exported from the Structurizr
```mermaid
graph LR
linkStyle default fill:#ffffff
subgraph diagram [Prism SaaS - Containers]
style diagram fill:#ffffff,stroke:#ffffff
1["<div style='font-weight: bold'>User</div><div style='font-size: 70%; margin-top: 0px'>[Person]</div>"]
style 1 fill:#08427b,stroke:#052e56,color:#ffffff
2["<div style='font-weight: bold'>Admin</div><div style='font-size: 70%; margin-top: 0px'>[Person]</div>"]
style 2 fill:#08427b,stroke:#052e56,color:#ffffff
subgraph 3 [Prism SaaS]
style 3 fill:#ffffff,stroke:#0b4884,color:#0b4884
subgraph group1 [Infrastructure Services]
style group1 fill:#ffffff,stroke:#cccccc,color:#cccccc,stroke-dasharray:5
21("<div style='font-weight: bold'>Admin App</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 21 fill:#438dd5,stroke:#2e6295,color:#ffffff
23("<div style='font-weight: bold'>Platform Backend</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 23 fill:#438dd5,stroke:#2e6295,color:#ffffff
26("<div style='font-weight: bold'>Argo CD</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 26 fill:#438dd5,stroke:#2e6295,color:#ffffff
28("<div style='font-weight: bold'>Platform DB</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 28 fill:#438dd5,stroke:#2e6295,color:#ffffff
end
subgraph group2 [Prism Enterprise Services]
style group2 fill:#ffffff,stroke:#cccccc,color:#cccccc,stroke-dasharray:5
10("<div style='font-weight: bold'>Manage App</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 10 fill:#438dd5,stroke:#2e6295,color:#ffffff
12("<div style='font-weight: bold'>Enterprise Service Backend</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 12 fill:#438dd5,stroke:#2e6295,color:#ffffff
end
subgraph group3 [Prism Mediator Services]
style group3 fill:#ffffff,stroke:#cccccc,color:#cccccc,stroke-dasharray:5
14("<div style='font-weight: bold'>Prism Mediator</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 14 fill:#438dd5,stroke:#2e6295,color:#ffffff
16("<div style='font-weight: bold'>MongoDB</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 16 fill:#438dd5,stroke:#2e6295,color:#ffffff
end
subgraph group4 [Prism Platform Dynamic Services]
style group4 fill:#ffffff,stroke:#cccccc,color:#cccccc,stroke-dasharray:5
31("<div style='font-weight: bold'>Prism Agent DB</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 31 fill:#438dd5,stroke:#2e6295,color:#ffffff
32("<div style='font-weight: bold'>Prism Agent #1</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 32 fill:#438dd5,stroke:#2e6295,color:#ffffff
38("<div style='font-weight: bold'>Prism Agent #2</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 38 fill:#438dd5,stroke:#2e6295,color:#ffffff
end
subgraph group5 [Prism Platform Identity Services]
style group5 fill:#ffffff,stroke:#cccccc,color:#cccccc,stroke-dasharray:5
18("<div style='font-weight: bold'>Prism Node</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 18 fill:#438dd5,stroke:#2e6295,color:#ffffff
19("<div style='font-weight: bold'>Prism Node DB</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 19 fill:#438dd5,stroke:#2e6295,color:#ffffff
end
4("<div style='font-weight: bold'>APISIX API Gateway</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 4 fill:#438dd5,stroke:#2e6295,color:#ffffff
7("<div style='font-weight: bold'>Teleport Gateway</div><div style='font-size: 70%; margin-top: 0px'>[Container]</div>")
style 7 fill:#438dd5,stroke:#2e6295,color:#ffffff
end
4-. "<div>Calls</div><div style='font-size: 70%'></div>" .->10
10-. "<div>Calls REST API</div><div style='font-size: 70%'></div>" .->12
4-. "<div>Calls REST/DIDComm API</div><div style='font-size: 70%'></div>" .->14
14-. "<div>Store the state</div><div style='font-size: 70%'></div>" .->16
18-. "<div>Store state</div><div style='font-size: 70%'></div>" .->19
7-. "<div>Calls</div><div style='font-size: 70%'></div>" .->21
12-. "<div>Call REST API</div><div style='font-size: 70%'></div>" .->23
21-. "<div>Call REST API</div><div style='font-size: 70%'></div>" .->23
23-. "<div>Manage Agents</div><div style='font-size: 70%'></div>" .->26
26-. "<div>Stores the topoloy of the<br />environment</div><div style='font-size: 70%'></div>" .->28
23-. "<div>Stores the state of the<br />environment</div><div style='font-size: 70%'></div>" .->28
4-. "<div>Calls REST API</div><div style='font-size: 70%'></div>" .->32
26-. "<div>Manage the instance lifecycle</div><div style='font-size: 70%'></div>" .->32
32-. "<div>Communicate over gRPC API</div><div style='font-size: 70%'></div>" .->18
32-. "<div>Store the state</div><div style='font-size: 70%'></div>" .->31
32-. "<div>Communicate over DIDComm</div><div style='font-size: 70%'></div>" .->14
4-. "<div>Calls REST API</div><div style='font-size: 70%'></div>" .->38
26-. "<div>Manage the instance lifecycle</div><div style='font-size: 70%'></div>" .->38
38-. "<div>Communicate over gRPC API</div><div style='font-size: 70%'></div>" .->18
38-. "<div>Store the state</div><div style='font-size: 70%'></div>" .->31
38-. "<div>Communicate over DIDComm</div><div style='font-size: 70%'></div>" .->14
1-. "<div>Calls</div><div style='font-size: 70%'></div>" .->4
2-. "<div>Calls</div><div style='font-size: 70%'></div>" .->7
end
```