Skip to content

Commit 92a1d0b

Browse files
committed
Update readme
1 parent d00a41c commit 92a1d0b

File tree

11 files changed

+298
-62
lines changed

11 files changed

+298
-62
lines changed

Cargo.lock

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 102 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,42 @@
88

99
<hr>
1010

11-
`sandpolis` is a **virtual estate monitoring/management tool** under active
12-
development.
11+
`sandpolis` is a **virtual estate monitoring/management tool** (VEM²) under
12+
active development.
1313

1414
<p align="center">
1515
<img src="https://raw.githubusercontent.com/fossable/sandpolis/master/.github/images/overview.png" />
1616
</p>
1717

18+
## Virtual estate
19+
20+
Virtual/digital estate is an all-encompassing term that generally refers to all
21+
of the (non-physical) assets in your possession. Some of them may be entirely
22+
virtual, like accounts on _github.com_. Others have a physical component as
23+
well, like a server in your closet, Raspberry Pi, or laptop.
24+
25+
All of these entities are part of your _virtual estate_ and are often
26+
intricately connected in various ways. As an example, you might have an SSH key
27+
or API token on your machine that grants access to repositories (a kind of
28+
digital asset) on Github. And suppose your machine also has an authorized key
29+
installed that allows access from another machine:
30+
31+
```
32+
┌──────────┐ SSH Key ┌──────────┐ API Token ┌───────────────────┐
33+
│Machine A ┼───────────►Machine B ┼─────────────► Github │
34+
└──────────┘ └──────────┘ │ │
35+
│ - Private repos │
36+
└───────────────────┘
37+
```
38+
39+
If you care about those repos, then Sandpolis can map out an attack surface that
40+
includes both `Machine A` and `Machine B`. If `Machine A` happens to have a weak
41+
password or one that's shared with another website, then the attack surface is
42+
consequently expanded with appropriate probabilities.
43+
44+
Mapping these relationships automatically is possible because Sandpolis runs an
45+
agent on `Machine A` and `Machine B` (and has API access to Github).
46+
1847
## Security Warning
1948

2049
Sandpolis is an extremely high-value attack target as it provides management
@@ -27,23 +56,36 @@ available:
2756

2857
- Users can be required to login with two-factor authentication codes.
2958

30-
- User permissions can restrict what users are able to do and on what instances.
31-
32-
- Agents can optionally run in _read only_ mode which still provides useful
33-
information, but prohibits all write operations. This can significantly
34-
mitigate potential damage in the event of server compromise.
59+
- User permissions restrict what users are able to do and on what instances.
3560

3661
Even with several layers of strong authentication, there's always risk that the
37-
Sandpolis server can be compromised. If the risks of "single point of
38-
compromise" outweigh the convenience of having a unified management interface,
39-
then **don't use Sandpolis**.
62+
Sandpolis server can be compromised. If the risks of introducing a "single point
63+
of compromise" outweigh the convenience of having a unified management
64+
interface, then **don't use Sandpolis**.
65+
66+
You can choose how much trust you allocate to the Sandpolis network. For
67+
example, agents can optionally run in _read only_ mode which still provides
68+
useful monitoring information, but prohibits all write operations (including
69+
agent updates). This can significantly mitigate potential damage in the event of
70+
server compromise.
4071

4172
## Layers
4273

43-
Features are organized into _layers_ that can be toggled on/off in the UI.
74+
Features are organized into _layers_ that can be toggled on/off in the UI. If
75+
you build Sandpolis from source, it's also easy to pick and choose what layers
76+
are included:
77+
78+
```sh
79+
# Build the Sandpolis server with remote desktop capabilities ONLY
80+
cargo build --no-default-features --features server --features layer-desktop
81+
```
4482

4583
### Account
4684

85+
Models online/offline accounts and their relationships to agent instances.
86+
Enables higher-order analysis of virtual estate like attack surface mapping and
87+
compromise tracing.
88+
4789
### Alert
4890

4991
Triggers user notifications when certain events are detected in the Sandpolis
@@ -57,24 +99,71 @@ Provides access to remote desktop capabilities.
5799
### Filesystem
58100

59101
Provides read/write access to agent filesystems. The Sandpolis client can also
60-
mount a remote filesystem.
102+
mount an agent's filesystem.
61103

62104
### Logging
63105

64106
### Package
65107

66-
Integrates with the package manager on agents to manages package versions.
108+
Integrates with package managers to monitor package versions.
67109

68110
### Probe
69111

70112
Probes are managable from the Sandpolis network, but don't run agent software.
71113
Instead, a remote Sandpolis agent instance connects to probes over a standard
72114
protocol like SSH, SNMP, Docker, etc.
73115

116+
You can interact with probes almost as if they were regular agents (as long as
117+
the gateway instance remains online).
118+
74119
### Shell
75120

76121
Provides an interactive remote shell.
77122

78123
### Tunnel
79124

80125
### User
126+
127+
## Installation
128+
129+
<details>
130+
<summary>Crates.io</summary>
131+
132+
![Crates.io Total Downloads](https://img.shields.io/crates/d/sandpolis)
133+
134+
#### Install from crates.io
135+
136+
```sh
137+
cargo install sandpolis
138+
```
139+
140+
</details>
141+
142+
<details>
143+
<summary>Docker</summary>
144+
145+
#### Install server from DockerHub
146+
147+
![Docker Pulls](https://img.shields.io/docker/pulls/sandpolis/server)
148+
![Docker Image Size](https://img.shields.io/docker/image-size/sandpolis/server)
149+
![Docker Stars](https://img.shields.io/docker/stars/sandpolis/server)
150+
151+
```yml
152+
# Docker compose
153+
services:
154+
sandpolis-server:
155+
image: sandpolis/server
156+
restart: unless-stopped
157+
```
158+
159+
#### Install client from DockerHub
160+
161+
![Docker Pulls](https://img.shields.io/docker/pulls/sandpolis/client)
162+
![Docker Image Size](https://img.shields.io/docker/image-size/sandpolis/client)
163+
![Docker Stars](https://img.shields.io/docker/stars/sandpolis/client)
164+
165+
```sh
166+
alias sandpolis-client="docker run --rm sandpolis/client"
167+
```
168+
169+
</details>

sandpolis-client/src/tui/help.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,40 @@
1-
use ratatui::{buffer::Buffer, crossterm::event::KeyCode, layout::Rect};
2-
use std::collections::HashMap;
1+
use ratatui::text::Text;
2+
use ratatui::widgets::Cell;
3+
use ratatui::{buffer::Buffer, crossterm::event::KeyCode, layout::Rect, widgets::WidgetRef};
4+
use ratatui::{
5+
layout::Constraint,
6+
style::{Style, Stylize},
7+
widgets::{Block, Row, Table},
8+
};
39

410
/// Shows help message
511
pub struct HelpWidget {
6-
pub keybindings: HashMap<KeyCode, String>,
12+
pub keybindings: Vec<(KeyCode, String)>,
713
}
814

915
impl HelpWidget {
1016
pub fn height(&self) -> u16 {
11-
todo!()
17+
self.keybindings.len() as u16
1218
}
1319
}
1420

1521
impl WidgetRef for HelpWidget {
1622
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
17-
let block = Block::default().borders(Borders::ALL);
18-
block.render(area, buf);
23+
let rows: Vec<Row> = self
24+
.keybindings
25+
.iter()
26+
.map(|(key, description)| {
27+
Row::new(vec![
28+
Cell::from(description.clone()).italic(),
29+
Cell::from(Text::from(key.to_string()).right_aligned()).bold(),
30+
])
31+
})
32+
.collect();
33+
34+
let widths = [Constraint::Percentage(90), Constraint::Percentage(10)];
35+
Table::new(rows, widths)
36+
.column_spacing(1)
37+
.style(Style::new().blue())
38+
.render_ref(area, buf);
1939
}
2040
}

sandpolis-client/src/tui/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use ratatui::{
77
widgets::{Widget, WidgetRef},
88
};
99
use std::time::Duration;
10+
use tokio::sync::broadcast::{Receiver, Sender};
1011
use tokio_stream::StreamExt;
1112

1213
pub mod help;
@@ -57,3 +58,5 @@ pub enum Message {
5758
FocusChanged,
5859
ServerSelected,
5960
}
61+
62+
pub type MessageBus<T> = (Sender<T>, Receiver<T>);

sandpolis-power/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ sandpolis-instance = { path = "../sandpolis-instance", version = "0.0.1" }
1616
sandpolis-network = { path = "../sandpolis-network", version = "0.0.1" }
1717
sandpolis-client = { path = "../sandpolis-client", version = "0.0.1" }
1818
sandpolis-database = { path = "../sandpolis-database", version = "0.0.1" }
19+
sandpolis-group = { path = "../sandpolis-group", version = "0.0.1" }
1920

2021
[features]
2122
agent = ["dep:axum", "dep:axum-macros"]

sandpolis-power/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use anyhow::Result;
22
use messages::{PowerRequest, PowerResponse};
3+
use sandpolis_group::GroupName;
34
use sandpolis_instance::InstanceId;
45
use sandpolis_network::NetworkLayer;
56
use serde::{Deserialize, Serialize};

sandpolis-server/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,8 @@ pub struct ServerBannerData {
6262
/// An image to display on the login screen
6363
#[serde(with = "serde_bytes")]
6464
pub image: Option<Vec<u8>>, // TODO validate with image decoder
65+
66+
/// Whether users are required to provide a second authentication mechanism
67+
/// on login
68+
pub mfa: bool,
6569
}

sandpolis/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ openraft = { git = "https://github.com/databendlabs/openraft", optional = true,
5656
"type-alias",
5757
] }
5858

59-
# Client exclusive
59+
# Terminal client exclusive
6060
ratatui = { workspace = true, optional = true }
6161
ratatui-image = { workspace = true, optional = true }
6262
image = { workspace = true, optional = true }
63+
tui-popup = "0.6.0"
6364

6465
[features]
6566
# Instances

0 commit comments

Comments
 (0)