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

Enable Istio-style SPIFFE IDs; custom namespaces, and trust domains #1011

Merged
merged 26 commits into from
Jun 25, 2024

Conversation

v0lkan
Copy link
Contributor

@v0lkan v0lkan commented Jun 25, 2024

Enable Istio-style SPIFFE IDs; custom namespaces, and trust domains

Description

This PR adds additional flexibility to VSecM deployments by enabling custom SPIFFE IDs
for workload identities, custom namespaces, and custom trust domains.

Changes

  • Update app/safe/internal/server/handle/route.go to fix a regression.
  • Introduce env.NameRegExpForWorkload() to allow matching workload ids from spiffe ids
    based on regular expressions.
  • Updated WorkloadIDAndParts(spiffeid string) (string, []string) to work with
    the above regexp; the implementation needs some simplification, which can be done
    as a follow-up PR.
  • Added stricter default values to VSecMSpiffeIdPrefixSafe, VSecMSpiffeIdPrefixSentinel, VSecMSpiffeIdPrefixWorkload, VSecMNameRegExpForWorkload.
  • Fix tests and deployment manifests accordingly.
  • created a values-custom.yaml to test the changes with an inline comment to how to use
    it. A follow-up PR will be created to add the test to integration test too.
  • Necessary documentation updates will be done as a separate PR too.

Test Policy Compliance

  • I have added or updated unit tests for my changes.
  • I have included integration tests where applicable.
  • All new and existing tests pass successfully.

Code Quality

  • I have followed the coding standards for this project.
  • I have performed a self-review of my code.
  • My code is well-commented, particularly in areas that may be difficult
    to understand.

Documentation

There are some doc updates. The rest will be completed separately.

Additional Comments

These changes will especially be helpful for OpenShift deployments.

Checklist

Before you submit this PR, please make sure:

  • You have read the contributing guidelines and
    especially the test policy.
  • You have thoroughly tested your changes.
  • You have followed all the contributing guidelines for this project.
  • You understand and agree that your contributions will be publicly available
    under the project's license.

By submitting this pull request, you confirm that my contribution is made under
the terms of the project's license and that you have the authority to grant
these rights.


Thank you for your contribution to VMware Secrets Manager
🐢⚡️!

v0lkan added 26 commits June 24, 2024 14:47
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
Signed-off-by: Volkan Özçelik <[email protected]>
@v0lkan v0lkan requested a review from BulldromeQ as a code owner June 25, 2024 21:16
@v0lkan v0lkan self-assigned this Jun 25, 2024
@v0lkan v0lkan requested review from ats0stv and farhan-pasha June 25, 2024 21:16
@v0lkan
Copy link
Contributor Author

v0lkan commented Jun 25, 2024

cc: @BulldromeQ these changes will be useful for our OpenShift deployment too, since the particular cluster that we were working on was creating its own custom ClusterSPIFFEIds and was using its own custom namespaces (instead of vsecm-system).

@v0lkan
Copy link
Contributor Author

v0lkan commented Jun 25, 2024

I summarized the changes in the PR body; yet, I’ll annotate the code as needed too.

@@ -31,6 +31,9 @@ VSECM_EKS_REGISTRY_URL ?= "public.ecr.aws/h8y1n7y7"
VSECM_NAMESPACE_SYSTEM ?= "vsecm-system"
VSECM_NAMESPACE_SPIRE ?= "spire-system"
VSECM_NAMESPACE_SPIRE_SERVER ?= "spire-server"
# VSECM_NAMESPACE_SYSTEM ?= "vsecm-system-custom"
# VSECM_NAMESPACE_SPIRE ?= "spire-system-custom"
# VSECM_NAMESPACE_SPIRE_SERVER ?= "spire-server-custom"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These commented out lines are useful to test the thing with the generated k8s manifests instead of directly using helm. — An alternative is to define the environment variables, or pass these as arguments to make. I wanted to keep them explicit as they double as documentation too.

@@ -70,6 +70,7 @@ const VSecMSidecarSuccessThreshold VarName = "VSECM_SIDECAR_SUCCESS_THRESHOLD"
const VSecMSpiffeIdPrefixSafe VarName = "VSECM_SPIFFEID_PREFIX_SAFE"
const VSecMSpiffeIdPrefixSentinel VarName = "VSECM_SPIFFEID_PREFIX_SENTINEL"
const VSecMSpiffeIdPrefixWorkload VarName = "VSECM_SPIFFEID_PREFIX_WORKLOAD"
const VSecMWorkloadNameRegExp VarName = "VSECM_WORKLOAD_NAME_REGEXP"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is new. It gives us the flexibility to capture any part of the SPIFFE ID as the workload’s id.

One restriction is; all regexp shall start with ^spifee://$trustDomain/ where $trustDomain is whichever trust domain has been configured.

It is also recommended for the regExps to end with a $ and make the matches as specific as possible whenever possible.

func NameRegExpForWorkload() string {
p := env.Value(env.VSecMWorkloadNameRegExp)
if p == "" {
p = string(env.VSecMNameRegExpForWorkloadDefault)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having default values in the codebase has both benefits, and liabilities; maybe we should create an ADR for this outlining why we prefer it that way (as opposed to, for example, using a configuration file, or a ConfigMap).

},
{
name: "safe_spiffeid_prefix_from_env",
setup: func() error {
return os.Setenv("VSECM_SPIFFEID_PREFIX_WORKLOAD", "spiffe://vsecm.com/workload/test/")
return os.Setenv("VSECM_SPIFFEID_PREFIX_WORKLOAD", "spiffe://vsecm.com/workload/test/ns/test/sa/test/n/test")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to the stricter SPIFFE ID validation, we had to update the tests to be stricter too. – the test do not pass if the ids do not conform to a certain pattern.

// `^spiffe://$trustDomain` prefix for extra security.
//
// This variable shall be treated as constant and should not be modified.
var spiffeRegexPrefixStart = "^spiffe://" + env.SpiffeTrustDomain() + "/"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentionally hard coded and kept reconfigurable because

  1. Any spiffe id has to start with spiffe:// as part of the standard and then followed by the trust domain.
  2. Starting the matcher with a ^ makes it more restrictive and more secure, since you cannot just use any regexp, and you have to match thing starting from the beginning of the string.

@@ -43,13 +47,18 @@ const spiffeRegexPrefixStart = "^"
//
// bool: `true` if the SPIFFE ID belongs to VSecM Sentinel, `false` otherwise.
func IsSentinel(spiffeid string) bool {
if !IsWorkload(spiffeid) {
return false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any VSecM entity is also a workload. So we run an IsWorkload() check before running other checks.

@@ -26,7 +26,7 @@ data:
resourceName: 98c9c988.spiffe.io
resourceNamespace: {{ .Values.global.spire.serverNamespace }}
clusterName: vsecm-cluster
trustDomain: vsecm.com
trustDomain: {{ .Values.global.spire.trustDomain }}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have missed this; the recent customization test helped us realize that :) .

@v0lkan v0lkan merged commit 2ac30f9 into main Jun 25, 2024
@v0lkan v0lkan deleted the ovolkan/params branch June 25, 2024 21:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant