Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement basic permission checks and Improve OIDC support. #187

Merged
merged 21 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ jobs:
name: "Extract config files from environment variables"
command: |
echo $ARMADA_CONFIG | base64 -d > armada_config.yaml
echo $ARMADA_USERS | base64 -d > armada_users.yaml
echo $EXECUTOR_CONFIG | base64 -d > executor_config.yaml
echo $EXECUTOR_API_CREDENTIALS | base64 -d > executor_api_credentials.yaml
- run:
name: "Deploy to services"
command: |
Expand Down
9 changes: 5 additions & 4 deletions cmd/armada/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ func loadUsersCredentialFile(config *configuration.ArmadaConfig) {
log.Error(err)
os.Exit(-1)
}
users := viper.GetStringMapString("users")

config.BasicAuth = configuration.AuthenticationConfig{
EnableAuthentication: true,
Users: users,
err = viper.Unmarshal(&config.BasicAuth)
if err != nil {
log.Error(err)
os.Exit(-1)
}
config.BasicAuth.EnableAuthentication = true
}
}
14 changes: 13 additions & 1 deletion cmd/armadactl/cmd/createQueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ func init() {
createQueueCmd.Flags().Float64(
"priorityFactor", 1,
"Set queue priority factor - lower number makes queue more important, must be > 0.")
createQueueCmd.Flags().StringArray(
"owners", []string{},
"Comma separated list of queue owners, defaults to current user.")
createQueueCmd.Flags().StringArray(
"groupOwners", []string{},
"Comma separated list of queue group owners, defaults to empty list.")
}

// createQueueCmd represents the createQueue command
Expand All @@ -29,12 +35,18 @@ Job priority is evaluated inside queue, queue has its own priority.`,
Run: func(cmd *cobra.Command, args []string) {
queue := args[0]
priority, _ := cmd.Flags().GetFloat64("priorityFactor")
owners, _ := cmd.Flags().GetStringArray("owners")
groups, _ := cmd.Flags().GetStringArray("groupOwners")

apiConnectionDetails := client.ExtractCommandlineArmadaApiConnectionDetails()

util.WithConnection(apiConnectionDetails, func(conn *grpc.ClientConn) {
client := api.NewSubmitClient(conn)
e := service.CreateQueue(client, &api.Queue{Name: queue, PriorityFactor: priority})
e := service.CreateQueue(client, &api.Queue{
Name: queue,
PriorityFactor: priority,
UserOwners: owners,
GroupOwners: groups})

if e != nil {
log.Error(e)
Expand Down
2 changes: 1 addition & 1 deletion cmd/executor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func loadCredentials(config *configuration.ExecutorConfiguration) {
username := viper.GetString(common.UsernameField)
password := viper.GetString(common.PasswordField)

config.Authentication = configuration.AuthenticationConfiguration{
config.BasicAuth = configuration.BasicAuthenticationConfiguration{
EnableAuthentication: true,
Username: username,
Password: password,
Expand Down
10 changes: 10 additions & 0 deletions config/armada/config.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

grpcPort: 50051
metricsPort: 9000
priorityHalfTime: 20m
Expand All @@ -15,3 +16,12 @@ eventsRedis:
poolSize: 1000
basicAuth:
enableAuthentication: false
anonymousAuth: true
permissionGroupMapping:
submit_jobs: ["everyone"]
submit_any_jobs: ["everyone"]
create_queue: ["everyone"]
cancel_jobs: ["everyone"]
cancel_any_jobs: ["everyone"]
watch_all_events: ["everyone"]
execute_jobs: ["everyone"]
2 changes: 1 addition & 1 deletion config/executor/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ task:
allocateSpareClusterCapacityInterval: 5s
armada:
url : "localhost:50051"
authentication:
basicAuth:
enableAuthentication: false
metricsPort: 9001
12 changes: 0 additions & 12 deletions deployment/armada/templates/configmap.yaml

This file was deleted.

10 changes: 1 addition & 9 deletions deployment/armada/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ spec:
args:
- --config
- /config/application_config.yaml
- --usersPath
- /config/users.yaml
resources:
{{ toYaml .Values.resources | indent 12 }}
ports:
Expand All @@ -40,9 +38,6 @@ spec:
- name: user-config
mountPath: /config/application_config.yaml
subPath: {{ include "armada.config.filename" . }}
- name: users
mountPath: /config/users.yaml
subPath: {{ include "armada.users.filename" . }}
readOnly: true
affinity:
podAntiAffinity:
Expand All @@ -58,8 +53,5 @@ spec:
topologyKey: kubernetes.io/hostname
volumes:
- name: user-config
configMap:
name: {{ include "armada.config.name" . }}
- name: users
secret:
secretName: {{ include "armada.users.name" . }}
secretName: {{ include "armada.config.name" . }}
10 changes: 5 additions & 5 deletions deployment/armada/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "armada.users.name" . }}
name: {{ include "armada.config.name" . }}
namespace: {{ .Release.Namespace }}
labels:
{{ include "armada.labels.all" . | indent 4 }}
type: Opaque
data:
{{ include "armada.users.filename" . }}: |
{{- if .Values.credentials }}
{{ toYaml .Values.credentials | b64enc | indent 4 }}
{{- end }}
{{ include "armada.config.filename" . }}: |
{{- if .Values.applicationConfig }}
{{ toYaml .Values.applicationConfig | b64enc | indent 4 }}
{{- end }}
12 changes: 0 additions & 12 deletions deployment/executor/templates/configmap.yaml

This file was deleted.

10 changes: 1 addition & 9 deletions deployment/executor/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ spec:
args:
- --config
- /config/application_config.yaml
- --apiCredentialsPath
- /config/api-credentials.yaml
- --inCluster
resources:
{{ toYaml .Values.resources | indent 12 }}
Expand All @@ -38,18 +36,12 @@ spec:
- name: user-config
mountPath: /config/application_config.yaml
subPath: {{ include "executor.config.filename" . }}
- name: api-credentials
mountPath: /config/api-credentials.yaml
subPath: {{ include "executor.api.credentials.filename" . }}
readOnly: true
nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
volumes:
- name: user-config
configMap:
name: {{ include "executor.config.name" . }}
- name: api-credentials
secret:
secretName: {{ include "executor.api.credentials.name" . }}
secretName: {{ include "executor.config.name" . }}
10 changes: 5 additions & 5 deletions deployment/executor/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "executor.api.credentials.name" . }}
name: {{ include "executor.config.name" . }}
namespace: {{ .Release.Namespace }}
labels:
{{ include "executor.labels.all" . | indent 4 }}
type: Opaque
data:
{{ include "executor.api.credentials.filename" . }}: |
{{- if .Values.credentials }}
{{ toYaml .Values.credentials | b64enc | indent 4 }}
{{- end }}
{{ include "executor.config.filename" . }}: |
{{- if .Values.applicationConfig }}
{{ toYaml .Values.applicationConfig | b64enc | indent 4 }}
{{- end }}
32 changes: 28 additions & 4 deletions docs/helm/executor.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ This document briefly outlines the customisation options of the Executor helm ch
| `terminationGracePeriodSeconds` | Executor termination grace period in seconds | `0` |
| `prometheus.enabled` | Flag to determine if Prometheus components are deployed or not. This should only be enabled if Prometheus is deployed and you want to scrape metrics from the executor component | `false` |
| `applicationConfig` | Config file override values, merged with /config/executor/config.yaml to make up the config file used when running the application | `nil` |
| `credentials` | The credentials used by the executor when communicating with the server component | `nil` |


### applicationConfig example
## Application Config

The applicationConfig section of the values file is purely used to override the default config for the executor component

Expand All @@ -33,7 +31,33 @@ applicationConfig:
url : "server.url.com:443"
```

### credentials example
### Credentials

#### Open Id

For connection to Armada server protected by open Id auth you can configure executor to perform Client Credentials flow.
To do this it is recommended to configure new client application with Open Id provider for executor and permission executor using custom scope.

For Amazon Cognito the configuration could look like this:
```yaml
openIdClientCredentialsAuth:
providerUrl: "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_*** your user pool id ***"
clientId: "***"
clientSecret: "***"
scopes: ["armada/executor"]
```

To authenticate with username and password instead you can use Resource Owner (Password) flow:
```yaml
OpenIdPasswordAuth:
providerUrl: "https://myopenidprovider.com"
clientId: "***"
scopes: []
username: "executor-service"
password: "***"
```

#### Basic Auth

The credentials section of the values file is used to provide the username/password used for communication with the server component

Expand Down
75 changes: 71 additions & 4 deletions docs/helm/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ This document briefly outlines the customisation options of the server helm char
| `replicas` | Number of replicas (pods) of the server component | `1` |
| `prometheus.enabled` | Flag to determine if Prometheus components are deployed or not. This should only be enabled if Prometheus is deployed and you want to scrape metrics from the server component | `false` |
| `applicationConfig` | Config file override values, merged with /config/armada/config.yaml to make up the config file used when running the application |`grpcPort: 50051` |
| `basicAuth` | List of valid users/passwords used to login to the application | `nil` |

## applicationConfig example

## Application Config

The applicationConfig section of the values file is purely used to override the default config for the server component

Expand Down Expand Up @@ -43,7 +43,33 @@ applicationConfig:
poolSize: 1000
```

## basicAuth example
### Authentication

Server can be configured with multiple authentication methods.

#### Anonymous users
To enable anonymous users on server include this in your config:
```yaml
anonymousAuth: true
```

#### OpenId Authentication

Armada can be configured to use tokens signed by OpenId provider for authentication.
**Currently only JWT tokens are supported.**

To determine group membership of particular user, armada will read jwt claim specified in configuration as `groupsClaim`.

For example configuration using Amazon Cognito as provider can look like this:
```yaml
openIdAuth:
providerUrl: "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_*** your user pool id ***"
groupsClaim: "cognito:groups"
```

#### Basic Authentication

**Note: Basic authentication is not recommended for production deployment.**

The basicAuth section of the values file is used to provide a list of valid username/password pairs.

Expand All @@ -54,5 +80,46 @@ As an example, this section is formatted as:
```yaml
basicAuth:
users:
"user1": "password1"
"user1":
password: "password1"
groups: ["administrator", "teamB"]
"user2":
password: "password1"
groups: ["teamA"]
```

### Permissions
Armada allows you to specify these permissions for user:

| Permission | Details
|--------------------|-------------------------------------------
| submit_jobs | Allows users submit jobs to their queue.
| submit_any_jobs | Allows users submit jobs to any queue.
| create_queue | Allows users submit jobs to create queue.
| cancel_jobs | Allows users cancel jobs from their queue.
| cancel_any_jobs | Allows users cancel jobs from any queue.
| watch_all_events | Allows for watching all events.
| execute_jobs | Protects apis used by executor, only executor service should have this permission

Permissions can be assigned to user by group membership, like this:

```yaml
permissionGroupMapping:
submit_jobs: ["teamA", "administrators"]
submit_any_jobs: ["administrators"]
create_queue: ["administrators"]
cancel_jobs: ["teamA", "administrators"]
cancel_any_jobs: ["administrators"]
watch_all_events: ["teamA", "administrators"]
execute_jobs: ["armada-executor"]
```

In case of Open Id access tokens, permissions can be assigned based on token scope.
This is useful when using clients credentials flow for executor component.

```yaml
permissionScopeMapping:
execute_jobs: ["armada/executor"]
```

By default every user (including anonymous one) is member of group `everyone`.
16 changes: 15 additions & 1 deletion docs/production-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ Once you have the Armada components running, you can interact with them via the

You can provide these with each invocation of `armadactl`, however this can be tiresome.

Instead you can try one of the options below:
Instead you can try one of the options below.

For server with Open Id authentication config file is required.

#### Config file

Expand All @@ -124,6 +126,18 @@ username: "user1"
password: "password1"
```

For Open Id protected server armadactl will perform PKCE flow opening web browser.
Config file should look like this:
```yaml
armadaUrl: "server.component.url.com:443"
openIdConnect:
providerUrl: "https://myproviderurl.com"
clientId: "***"
localPort: 26354
useAccessToken: true
scopes: []
```

#### Persistent config

Building on the config file above. If you store the config file as `$HOME/.armadactl`
Expand Down
Loading