Skip to content

Commit

Permalink
[artemiscloud#16] Implementing security for api-server
Browse files Browse the repository at this point in the history
  • Loading branch information
howardgao committed Nov 20, 2024
1 parent b13545d commit 3ebb23b
Show file tree
Hide file tree
Showing 26 changed files with 2,728 additions and 301 deletions.
10 changes: 7 additions & 3 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ SERVER_KEY=/var/serving-cert/tls.key
# replace the token in production deployment
SECRET_ACCESS_TOKEN=1e13d44f998dee277deae621a9012cf300b94c91

# to trust jolokia certs
NODE_TLS_REJECT_UNAUTHORIZED='0'

# logging
LOG_LEVEL='info'
ENABLE_REQUEST_LOG='false'

# security
API_SERVER_SECURITY_ENABLED=false
USERS_FILE_URL=.users.json
ROLES_FILE_URL=.roles.json
ENDPOINTS_FILE_URL=.endpoints.json
ACCESS_CONTROL_FILE_URL=.access.json
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,13 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# vs code config
.vscode

# security files
.users.json
.roles.json
.endpoints.json
.access.json

23 changes: 23 additions & 0 deletions .test.access.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"endpoints": [
{
"name": "broker1",
"roles": ["role1", "manager"]
},
{
"name": "broker2",
"roles": ["role2", "manager"]
},
{
"name": "broker3",
"roles": ["manager"]
},
{
"name": "broker4",
"roles": ["manager"]
}
],
"admin": {
"roles": ["manager"]
}
}
57 changes: 57 additions & 0 deletions .test.endpoints.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"endpoints": [
{
"name": "broker1",
"url": "http://127.0.0.1:8161",
"auth": [
{
"scheme": "basic",
"data": {
"username": "guest",
"password": "guest"
}
}
]
},
{
"name": "broker2",
"url": "http://127.0.0.2:8161",
"auth": [
{
"scheme": "basic",
"data": {
"username": "guest",
"password": "guest"
}
}
]
},
{
"name": "broker3",
"url": "http://127.0.0.3:8161",
"auth": [
{
"scheme": "basic",
"data": {
"username": "guest",
"password": "guest"
}
}
]
},
{
"name": "broker4",
"url": "https://artemis-broker-jolokia-0-svc-ing-default.artemiscloud.io:443",
"jolokiaPrefix": "/jolokia/",
"auth": [
{
"scheme": "cert",
"data": {
"certpath": "test-api-server.crt",
"keypath": "test-api-server.key"
}
}
]
}
]
}
24 changes: 24 additions & 0 deletions .test.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

PLUGIN_VERSION=1.0.0
PLUGIN_NAME='ActiveMQ Artemis Jolokia api-server'

# dev cert
SERVER_CERT=/var/serving-cert/tls.crt
SERVER_KEY=/var/serving-cert/tls.key

# replace the token in production deployment
SECRET_ACCESS_TOKEN=1e13d44f998dee277deae621a9012cf300b94c91

# to trust jolokia certs
NODE_TLS_REJECT_UNAUTHORIZED='0'

# logging
LOG_LEVEL='debug'
ENABLE_REQUEST_LOG=false

# security
API_SERVER_SECURITY_ENABLED=true
USERS_FILE_URL=.test.users.json
ROLES_FILE_URL=.test.roles.json
ENDPOINTS_FILE_URL=.test.endpoints.json
ACCESS_CONTROL_FILE_URL=.test.access.json
16 changes: 16 additions & 0 deletions .test.roles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"roles": [
{
"name": "role1",
"uids": ["user1"]
},
{
"name": "role2",
"uids": ["user1", "user2"]
},
{
"name": "manager",
"uids": ["root"]
}
]
}
18 changes: 18 additions & 0 deletions .test.users.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"users": [
{
"id": "user1",
"email": "user1@example.com",
"hash": "$2a$12$nv9iV5/UNuV4Mdj1Jf8zfuUraqboSRtSQqCmtOc4F7rdwmOb9IzNu"
},
{
"id": "user2",
"hash": "$2a$12$VHZ9aJ5A87YeFop4xVW.aOMm95ClU.EviyT9o0i8HYLdG6w6ctMfW"
},
{
"id": "root",
"email": "user3@example.com",
"hash": "$2a$12$VHZ9aJ5A87YeFop4xVW.aOMm95ClU.EviyT9o0i8HYLdG6w6ctMfW"
}
]
}
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,54 @@ In production you should override it with your own secret.
The jwt-key-gen.sh is a tool to generate a random key and used in Dockerfile.
It makes sure when you build the api server image a new random key is used.

## Security Model of the API Server

The API Server provides a security model that provides authentication and authorization of incoming clients.
The security can be enabled/disabled (i.e. via `API_SERVER_SECURITY_ENABLED` env var)

### Authentication

Currently the api server support `jwt` token authentication.

#### The login api

The login api is defined in openapi.yml

```yaml
/server/login
```

A client logs in to an api server by sending a POST request to the login path. The request body contains login information (i.e. username and password for jwt authentication type)

Please refer to [api.md](api.md) for details of the log api.

Currently the security manager uses local file to store user's info. The default users file name is `.users.json`
The users file name can be configured using `USERS_FILE_URL` env var. See `.test.users.json` for sample values.

### Authorization

The server uses RBAC (Role Based Access Control) authorization. User/role mappings are stored in a local file. By default the file
name is `.roles.json` and can be configured using `ROLES_FILE_URL` env var. See `.test.roles.json` for sample values.

The permissions are defined in a local file. By default the file name is `.access.json` and can be configured using
`ACCESS_CONTROL_FILE_URL` env var. See `.test.access.json` for sample values.

### Endpoints Management

The server keeps a list of jolokia endpoints for clients to access. The endpoints are loaded from a local file named
`.endpoints.json`. Each top leve entry represents a jolokia endpoint. An entry has a unique name and details to access the jolokia api. See `.test.endpoints.json` for sample values.

### Accessing a jolokia endpoint

When an authenticated client sends a request to the api-server, it should present its token in the request header

'Authorization: Bearer `token`'

It also need to give the `targetEndpoint` in the query part of the request if the request is to access an jolokia endpoint.

For example `/execBrokerOperation?targetEndpoint=broker1`.

### Direct Proxy

Direct Proxy means a client can pass a broker's endpoint info to the api-server in order to access it via the api-server.
For example the [self-provisioning plugin](https://github.com/artemiscloud/activemq-artemis-self-provisioning-plugin) uses this api to access the jolokia of a broker's jolokia endpoint.
Loading

0 comments on commit 3ebb23b

Please sign in to comment.