Skip to content

Commit

Permalink
Implement token-exchange to get scoped token for AWS with testing.hub…
Browse files Browse the repository at this point in the history
….cryptomator.org (#41 #10 #23 #3).
  • Loading branch information
chenkins committed Dec 14, 2023
1 parent 7b319f6 commit cd23a98
Show file tree
Hide file tree
Showing 16 changed files with 335 additions and 151 deletions.
3 changes: 1 addition & 2 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,4 @@ nb-configuration.xml
*.rej

# Local environment
.env
/config/application.properties
.env
151 changes: 92 additions & 59 deletions backend/CIPHERDUCK.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ MinIO
### Setup MinIO

Documentation

* [MinIO OpenID Connect Access Management](https://min.io/docs/minio/linux/administration/identity-access-management/oidc-access-management.html)
* [MinIO Client Reference `mc idp openid`](https://min.io/docs/minio/linux/reference/minio-mc/mc-idp-openid.html)
* [MinIO Security Token Service `AssumeRoleWithWebIdentity](https://min.io/docs/minio/linux/developers/security-token-service/AssumeRoleWithWebIdentity.html)



#### Policy and OIDC provider for MinIO
Add role for creating buckets with prefix `cipherduck` and uploading `vault.cryptomator`, as well as RW to access to buckets through `aud` claim in JWT token:
see

Add role for creating buckets with prefix `cipherduck` and uploading `vault.cryptomator`, as well as RW to access to
buckets through `aud` claim in JWT token:
see
[cipherduck.json](src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Fminio%2Fcipherduckpolicy.json).

Side-note: MinIO does not allow for multiple OIDC providers with the same client ID:
Expand All @@ -25,15 +26,13 @@ Side-note: MinIO does not allow for multiple OIDC providers with the same client
This is not a problem as we leave the claim specifying the vault unset or pointing to a non-existing vault.




```shell
mc alias set myminio http://127.0.0.1:9000 minioadmin minioadmin
mc admin policy create myminio cipherduck src/main/resources/cipherduck/setup/minio/cipherduckpolicy.json
```

Add a new OIDC provider using the policy:

```shell
mc idp openid add myminio cryptomator \
config_url="http://keycloak:8180/realms/cryptomator/.well-known/openid-configuration" \
Expand Down Expand Up @@ -62,6 +61,7 @@ mc admin service restart myminio
```

Extract the policy ARN:

```shell
mc idp openid ls myminio feature/cipherduck
╭───────────────────────────────────────────────────────────────────────╮
Expand All @@ -82,47 +82,70 @@ mc idp openid info myminio
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```


### Hub configuration

```properties
backends.backends[0].id=http://minio:9000
backends.backends[0].name=MinIO S3 STS
backends.backends[0].bucket-prefix=cipherduck
backends.backends[0].s3-type=minio
backends.backends[0].region=eu-central-1
backends.backends[0].jwe.protocol=s3
backends.backends[0].jwe.vendor=s3-sts-http
backends.backends[0].jwe.hostname=minio
backends.backends[0].jwe.port=9000
backends.backends[0].jwe.scheme=http
backends.backends[0].jwe.sts-endpoint=http://minio:9000
backends.backends[0].jwe.oauth-redirect-url=x-cipherduck-action:oauth
backends.backends[0].jwe.oauth-authorization-url=http://localhost:8180/realms/cryptomator/protocol/openid-connect/auth
backends.backends[0].jwe.oauth-token-url=http://localhost:8180/realms/cryptomator/protocol/openid-connect/token
backends.backends[0].jwe.oauth-client-id=cryptomator
backends.backends[0].jwe.authorization=AuthorizationCode
```
See [application.properties](config%2Fapplication.properties)

AWS
---



### Setup AWS

TODO https://github.com/chenkins/cipherduck-hub/issues/23 create OIDC provider
#### Setup AWS: OIDC provider

#### OIDC provider
See
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html

```shell
openssl s_client -servername login1.staging.cryptomator.cloud -showcerts -connect login1.staging.cryptomator.cloud:443

cat login1.staging.cryptomator.cloud.crt
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----

openssl x509 -in login1.staging.cryptomator.cloud.crt -fingerprint -sha1 -noout | sed -e 's/://g' | sed -e 's/SHA1 Fingerprint=//'
933C6DDEE95C9C41A40F9F50493D82BE03AD87BF

aws iam create-open-id-connect-provider --url https://testing.hub.cryptomator.org/kc/realms/cipherduck/ --client-id-list cryptomator --thumbprint-list DEF08E0D6AC5577D3436E4D6AA8E9F13721B00DD
{
"OpenIDConnectProviderArn": "arn:aws:iam::930717317329:oidc-provider/login1.staging.cryptomator.cloud/realms/cipherduck"
}

aws iam list-open-id-connect-providers
aws iam get-open-id-connect-provider --open-id-connect-provider-arn "arn:aws:iam::930717317329:oidc-provider/login1.staging.cryptomator.cloud/realms/cipherduck" feature/cipherduck

aws iam get-open-id-connect-provider --open-id-connect-provider-arn "arn:aws:iam::930717317329:oidc-provider/login1.staging.cryptomator.cloud/realms/cipherduck"
{
"Url": "login1.staging.cryptomator.cloud/realms/cipherduck",
"ClientIDList": [
"sts.amazonaws.com",
"cipherduckclient",
"cryptomator"
],
"ThumbprintList": [
Expand All @@ -132,24 +155,43 @@ aws iam get-open-id-connect-provider --open-id-connect-provider-arn "arn:aws:iam
"Tags": []
}
```
Add role for creating buckets with prefix `cipherduck` and uploading `vault.cryptomator`,
see
[createbucketpermissionpolicy.json](src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcreatebucketpermissionpolicy.json)
and
[createbuckettrustpolicy.json](./src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcreatebuckettrustpolicy.json).

#### Setup AWS: roles

Add role for creating buckets with prefix `cipherduck` and uploading `vault.cryptomator`,
see

* [createbucketpermissionpolicy.json](src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcreatebucketpermissionpolicy.json)
* [createbuckettrustpolicy.json](./src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcreatebuckettrustpolicy.json)

Add roles for role chaining:

* [cipherduck_chain_01_permissionpolicy.json](src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcipherduck_chain_01_permissionpolicy.json)
* [cipherduck_chain_01_trustpolicy.json](src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcipherduck_chain_01_trustpolicy.json)
* [cipherduck_chain_02_permissionpolicy.json](src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcipherduck_chain_02_permissionpolicy.json)
* [cipherduck_chain_02_trustpolicy.json](src%2Fmain%2Fresources%2Fcipherduck%2Fsetup%2Faws%2Fcipherduck_chain_02_trustpolicy.json)

```shell
aws iam create-role --role-name cipherduck-createbucket --assume-role-policy-document file://src/main/resources/cipherduck/setup/createbuckettrustpolicy.json
aws iam put-role-policy --role-name cipherduck-createbucket --policy-name cipherduck-createbucket --policy-document file://src/main/resources/cipherduck/setup/createbucketpermissionpolicy.json
aws iam create-role --role-name cipherduck-createbucket --assume-role-policy-document file://src/main/resources/cipherduck/setup/aws/createbuckettrustpolicy.json
aws iam put-role-policy --role-name cipherduck-createbucket --policy-name cipherduck-createbucket --policy-document file://src/main/resources/cipherduck/setup/aws/createbucketpermissionpolicy.json


aws iam create-role --role-name cipherduck_chain_01 --assume-role-policy-document file://src/main/resources/cipherduck/setup/aws/cipherduck_chain_01_trustpolicy.json
aws iam put-role-policy --role-name cipherduck_chain_01 --policy-name cipherduck_chain_01 --policy-document file://src/main/resources/cipherduck/setup/aws/cipherduck_chain_01_permissionpolicy.json

sleep 10;

aws iam create-role --role-name cipherduck_chain_02 --assume-role-policy-document file://src/main/resources/cipherduck/setup/aws/cipherduck_chain_02_trustpolicy.json
aws iam put-role-policy --role-name cipherduck_chain_02 --policy-name cipherduck_chain_02 --policy-document file://src/main/resources/cipherduck/setup/aws/cipherduck_chain_02_permissionpolicy.json
```

#### checking
Checking roles:

```shell
aws iam get-role-policy --role-name cipherduck-createbucket
aws iam get-role --role-name cipherduck-createbucket
aws iam get-role-policy --role-name cipherduck-createbucket --policy-name cipherduck-createbucket
```


```shell
TOKEN=`curl -v -X POST https://login1.staging.cryptomator.cloud/realms/cipherduck/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
Expand All @@ -165,25 +207,16 @@ aws sts assume-role-with-web-identity --role-arn "arn:aws:iam::930717317329:role

### Hub configuration

```properties
backends.backends[1].id=https://sts.amazonaws.com
backends.backends[1].name=AWS S3 STS
backends.backends[1].bucket-prefix=cipherduck
backends.backends[1].s3-type=aws
backends.backends[1].oidc-provider=arn:aws:iam::XXXX:oidc-provider/login1.staging.cryptomator.cloud/realms/cipherduck
backends.backends[1].sts-role-arn-prefix=arn:aws:iam::XXXX:role/
backends.backends[1].region=eu-central-1
backends.backends[1].jwe.protocol=s3
backends.backends[1].jwe.vendor=s3-sts-https
backends.backends[1].jwe.oauth-redirect-url=x-cipherduck-action:oauth
backends.backends[1].jwe.oauth-authorization-url=https://login1.staging.cryptomator.cloud/realms/cipherduck/protocol/openid-connect/auth
backends.backends[1].jwe.oauth-token-url=https://login1.staging.cryptomator.cloud/realms/cipherduck/protocol/openid-connect/token
backends.backends[1].jwe.oauth-client-id=cryptomator
backends.backends[1].jwe.authorization=AuthorizationCode
```
See [application.properties](config%2Fapplication.properties)


### AWS cleanup

```shell
aws iam delete-role-policy --role-name cipherduck-createbucket --policy-name cipherduck-createbucket
aws iam delete-role --role-name cipherduck-createbucket
aws iam delete-role-policy --role-name cipherduck_chain_01 --policy-name cipherduck_chain_01
aws iam delete-role --role-name cipherduck_chain_01
aws iam delete-role-policy --role-name cipherduck_chain_02 --policy-name cipherduck_chain_02
aws iam delete-role --role-name cipherduck_chain_02
```
44 changes: 44 additions & 0 deletions backend/config/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# keep storage configuration properties separate for now (see https://quarkus.io/guides/config-reference)
backends.backends[0].id=http://minio:9000
backends.backends[0].name=MinIO S3 STS
backends.backends[0].bucket-prefix=cipherduck
backends.backends[0].s3-type=minio
backends.backends[0].region=eu-central-1
backends.backends[0].jwe.protocol=s3
# role for cryptomatorhub client
#backends.backends[0].sts-role-arn=arn:minio:iam:::role/HGKdlY4eFFsXVvJmwlMYMhmbnDE
# role for cryptomatorhub client
backends.backends[0].sts-role-arn=arn:minio:iam:::role/IqZpDC5ahW_DCAvZPZA4ACjEnDE
backends.backends[0].jwe.vendor=s3-sts-http
backends.backends[0].jwe.hostname=minio
backends.backends[0].jwe.port=9000
backends.backends[0].jwe.scheme=http
backends.backends[0].jwe.sts-endpoint=http://minio:9000
backends.backends[0].jwe.oauth-redirect-url=x-cipherduck-action:oauth
backends.backends[0].jwe.oauth-authorization-url=https://testing.hub.cryptomator.org/kc/realms/cipherduck/protocol/openid-connect/auth
backends.backends[0].jwe.oauth-token-url=https://testing.hub.cryptomator.org/kc/realms/cipherduck/protocol/openid-connect/token
#backends.backends[0].jwe.oauth-authorization-url=http://keycloak:8180/realms/cryptomator/protocol/openid-connect/auth
#backends.backends[0].jwe.oauth-token-url=http://keycloak:8180/realms/cryptomator/protocol/openid-connect/token
backends.backends[0].jwe.oauth-client-id=cryptomator
backends.backends[0].jwe.authorization=AuthorizationCode
# role for cryptomator client
backends.backends[0].jwe.sts-role-arn=arn:minio:iam:::role/IqZpDC5ahW_DCAvZPZA4ACjEnDE

backends.backends[1].id=https://sts.amazonaws.com
backends.backends[1].name=AWS S3 STS
backends.backends[1].bucket-prefix=cipherduck
backends.backends[1].s3-type=aws
backends.backends[1].oidc-provider=arn:aws:iam::930717317329:oidc-provider/testing.hub.cryptomator.org/kc/realms/cipherduck
backends.backends[1].sts-role-arn=arn:aws:iam::930717317329:role/cipherduck-createbucket
backends.backends[1].region=eu-central-1
backends.backends[1].jwe.protocol=s3
backends.backends[1].jwe.vendor=s3-sts-https
backends.backends[1].jwe.oauth-redirect-url=x-cipherduck-action:oauth
#backends.backends[1].jwe.oauth-authorization-url=https://login1.staging.cryptomator.cloud/realms/cipherduck/protocol/openid-connect/auth
#backends.backends[1].jwe.oauth-token-url=https://login1.staging.cryptomator.cloud/realms/cipherduck/protocol/openid-connect/token
backends.backends[1].jwe.oauth-authorization-url=https://testing.hub.cryptomator.org/kc/realms/cipherduck/protocol/openid-connect/auth
backends.backends[1].jwe.oauth-token-url=https://testing.hub.cryptomator.org/kc/realms/cipherduck/protocol/openid-connect/token
backends.backends[1].jwe.oauth-client-id=cryptomator
backends.backends[1].jwe.authorization=AuthorizationCode
backends.backends[1].jwe.sts-role-arn=arn:aws:iam::930717317329:role/cipherduck_chain_01
backends.backends[1].jwe.sts-role-arn2=arn:aws:iam::930717317329:role/cipherduck_chain_02
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ public interface VaultJWEBackend {
@JsonProperty("stsRoleArn")
Optional<String> stsRoleArn();

@JsonProperty("stsRoleArn2")
Optional<String> stsRoleArn2();

@JsonProperty("stsDurationSeconds")
Optional<Integer> stsDurationSeconds();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@
import java.util.Optional;

public record VaultJweBackendDto(
String protocol,
Optional<String> vendor,
Optional<String> hostname,
Optional<String> scheme,
Optional<Integer> port,
Optional<String> region,
Optional<String> stsEndpoint,
Optional<String> stsRoleArn,
Optional<Integer> stsDurationSeconds,
Optional<String> authorization,
Optional<String> oauthAuthorizationUrl,
Optional<String> oauthTokenUrl,
Optional<String> oauthClientId,
Optional<String> oauthRedirectUrl,
Optional<String> usernameConfigurable,
Optional<String> passwordConfigurable,
Optional<String> tokenConfigurable
String protocol,
Optional<String> vendor,
Optional<String> hostname,
Optional<String> scheme,
Optional<Integer> port,
Optional<String> region,
Optional<String> stsEndpoint,
Optional<String> stsRoleArn,
Optional<String> stsRoleArn2,
Optional<Integer> stsDurationSeconds,
Optional<String> authorization,
Optional<String> oauthAuthorizationUrl,
Optional<String> oauthTokenUrl,
Optional<String> oauthClientId,
Optional<String> oauthRedirectUrl,
Optional<String> usernameConfigurable,
Optional<String> passwordConfigurable,
Optional<String> tokenConfigurable
) implements VaultJWEBackend {
}
Loading

0 comments on commit cd23a98

Please sign in to comment.