Skip to content

Commit

Permalink
feat: Vault tokens are now identity-based instead of anonymous (#4327)
Browse files Browse the repository at this point in the history
This is an internal refactoring of security-secretstore-setup,
security-file-token-provider, and security-spiffe-token-provider
to generate Vault tokens that are based on a Vault identity
instead of being anonymous tokens with an attached ACL.

The consequence of this refactoring is that the token
issuing components of EdgeX run with fewer required privileges
than before, and it is possible to ask Vault for a
verifiable JWT-based identity assertion of an EdgeX service.

Signed-off-by: Bryon Nevis <[email protected]>
  • Loading branch information
bnevis-i authored Feb 8, 2023
1 parent cb6527c commit fd143bc
Show file tree
Hide file tree
Showing 18 changed files with 458 additions and 270 deletions.
96 changes: 77 additions & 19 deletions cmd/security-file-token-provider/res/token-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,61 @@
"support-scheduler": {
"edgex_use_defaults": true
},
"security-secretstore-setup": {
"security-proxy-auth": {
"edgex_use_defaults": true
},
"security-proxy-setup": {
"edgex_use_defaults": true,
"custom_policy": {
"path": {
"secret/edgex/security-proxy-setup/kong-tls": {
"identity/entity/name": {
"capabilities": [
"list"
]
},
"identity/entity/name/*": {
"capabilities": [
"list",
"read",
"create",
"update",
"delete"
]
},
"secret/edgex/redis/*": {
"identity/entity-alias": {
"capabilities": [
"create",
"update"
]
},
"identity/oidc/role": {
"capabilities": [
"list"
]
},
"identity/oidc/role/*": {
"capabilities": [
"create",
"update"
]
},
"auth/userpass/users/*": {
"capabilities": [
"create",
"update"
]
},
"sys/auth": {
"capabilities": [
"read"
]
},
"sys/policies/acl": {
"capabilities": [
"list"
]
},
"sys/policies/acl/edgex-user-*": {
"capabilities": [
"list",
"read",
"create",
"update",
Expand All @@ -57,35 +96,54 @@
}
}
},
"security-proxy-setup": {
"edgex_use_defaults": true
},
"security-file-token-provider": {
"edgex_use_defaults": true
},
"security-spiffe-token-provider": {
"edgex_use_defaults": true,
"custom_policy": {
"path": {
"auth/token/create": {
"identity/entity/name": {
"capabilities": [
"list"
]
},
"identity/entity/name/*": {
"capabilities": [
"read",
"create",
"update",
"sudo"
"delete"
]
},
"auth/token/create-orphan": {
"identity/entity-alias": {
"capabilities": [
"create",
"update",
"sudo"
"update"
]
},
"identity/oidc/role": {
"capabilities": [
"list"
]
},
"auth/token/create/*": {
"identity/oidc/role/*": {
"capabilities": [
"create",
"update",
"sudo"
"update"
]
},
"auth/userpass/users/*": {
"capabilities": [
"create",
"update"
]
},
"sys/auth": {
"capabilities": [
"read"
]
},
"sys/policies/acl": {
"capabilities": [
"list"
]
},
"sys/policies/acl/edgex-service-*": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ ConfigFile = "res-file-token-provider/token-config.json"
OutputDir = "/tmp/edgex/secrets"
OutputFilename = "secrets-token.json"
DefaultTokenTTL = "1h"
DefaultJWTTTL = "15m"
UserPassMountPoint = "userpass"
11 changes: 11 additions & 0 deletions cmd/security-spiffe-token-provider/res/configuration.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ Port = 6379
Timeout = 5000
Type = "redisdb"


[TokenConfig]
#PrivilegedTokenPath = "UNUSED"
#ConfigFile = "UNUSED"
#OutputDir = "UNUSED"
#OutputFilename = "UNUSED"
DefaultTokenTTL = "1h"
DefaultJWTTTL = "15m"
UserPassMountPoint = "userpass"


[SPIFFE]
EndpointSocket = "/tmp/edgex/secrets/spiffe/public/api.sock"
TrustDomain = "edgexfoundry.org"
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Intel Corporation
// Copyright (c) 2019-2023 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
Expand All @@ -11,23 +11,30 @@
// or implied. See the License for the specific language governing permissions and limitations under
// the License.
//
// SPDX-License-Identifier: Apache-2.0'
// SPDX-License-Identifier: Apache-2.0
//

package fileprovider
package common

func makeDefaultTokenPolicy(serviceName string) map[string]interface{} {
func MakeDefaultTokenPolicy(serviceName string) map[string]interface{} {
// protected path for secret/
protectedPath := "secret/edgex/" + serviceName + "/*"
capabilities := []string{"create", "update", "delete", "list", "read"}
acl := map[string]interface{}{"capabilities": capabilities}
secretsPath := "secret/edgex/" + serviceName + "/*"
secretsAcl := map[string]interface{}{"capabilities": []string{"create", "update", "delete", "list", "read"}}
// path for consul tokens
registryCredsPath := "consul/creds/" + serviceName
registryCredsCapabilities := []string{"read"}
registryCredsACL := map[string]interface{}{"capabilities": registryCredsCapabilities}
registryCredsACL := map[string]interface{}{"capabilities": []string{"read"}}
// allow request identity JWT
jwtRequestPath := "identity/oidc/token/" + serviceName
jwtRequestACL := map[string]interface{}{"capabilities": []string{"read"}}
// allow introspect JWT
jwtIntrospectPath := "identity/oidc/introspect"
jwtIntrospectACL := map[string]interface{}{"capabilities": []string{"create", "update"}}
// access spec
pathObject := map[string]interface{}{
protectedPath: acl,
secretsPath: secretsAcl,
registryCredsPath: registryCredsACL,
jwtRequestPath: jwtRequestACL,
jwtIntrospectPath: jwtIntrospectACL,
}
retval := map[string]interface{}{"path": pathObject}
return retval
Expand All @@ -40,18 +47,14 @@ func makeDefaultTokenPolicy(serviceName string) map[string]interface{} {
},
"consul/creds/service-name": {
"capabilities": [ "read" ]
},
"identity/oidc/token/service-name": {
"capabilities": [ "read" ]
},
"identity/oidc/introspect": {
"capabilities": [ "create", "update" ]
}
}
}
*/
}

func makeDefaultTokenParameters(serviceName string, defaultTTL string, defaultPeriod string) map[string]interface{} {
return map[string]interface{}{
"display_name": serviceName,
"no_parent": true,
"ttl": defaultTTL,
"period": defaultPeriod,
"policies": []string{"edgex-service-" + serviceName},
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Intel Corporation
// Copyright (c) 2019-2023 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
Expand All @@ -11,9 +11,9 @@
// or implied. See the License for the specific language governing permissions and limitations under
// the License.
//
// SPDX-License-Identifier: Apache-2.0'
// SPDX-License-Identifier: Apache-2.0
//
package fileprovider
package common

import (
"encoding/json"
Expand All @@ -24,7 +24,7 @@ import (

func TestDefaultTokenPolicy(t *testing.T) {
// Act
policies := makeDefaultTokenPolicy("service-name")
policies := MakeDefaultTokenPolicy("service-name")

// Assert
bytes, err := json.Marshal(policies)
Expand All @@ -39,21 +39,14 @@ func TestDefaultTokenPolicy(t *testing.T) {
"consul/creds/service-name": map[string]interface{}{
"capabilities": []string{"read"},
},
"identity/oidc/token/service-name": map[string]interface{}{
"capabilities": []string{"read"},
},
"identity/oidc/introspect": map[string]interface{}{
"capabilities": []string{"create", "update"},
},
},
}

require.Equal(t, expected, policies)
}

func TestDefaultTokenParameters(t *testing.T) {
// Act
parameters := makeDefaultTokenParameters("service-name", "1h", "1h")

// Assert
bytes, err := json.Marshal(parameters)
require.NoError(t, err)

expected := `{"display_name":"service-name","no_parent":true,"period":"1h","policies":["edgex-service-service-name"],"ttl":"1h"}`
actual := string(bytes)
require.Equal(t, expected, actual)
}
Loading

0 comments on commit fd143bc

Please sign in to comment.