-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
Istio Citadel Agent integrates with Vault CA providers #10638
Istio Citadel Agent integrates with Vault CA providers #10638
Conversation
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
fa237ee
to
2e017ad
Compare
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
f17c8bc
to
c55e0f1
Compare
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
c55e0f1
to
221dc94
Compare
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
221dc94
to
1c437ea
Compare
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
security/pkg/nodeagent/caclient/providers/vault1/client_test.go
Outdated
Show resolved
Hide resolved
) | ||
|
||
const ( | ||
googleCAName = "GoogleCA" | ||
citadelName = "Citadel" | ||
vaultCAName1 = "VaultCA1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you put "1" in the name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: changed to VaultCA per discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} | ||
|
||
// NewVaultClient create a CA client for the Vault provider 1. | ||
func NewVaultClient1(tls bool, tlsRootCert []byte, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. If you want to add another Vault client in the future, try to give it a more descriptive name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: changed to VaultClient per discussion.
var client *api.Client | ||
var err error | ||
if tls { | ||
client, err = createVaultClientTLS(vaultAddr, tlsRootCert) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: createVaultTLSClient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
// CSR Sign calls Vault to sign a CSR. | ||
func (c *vaultClient1) CSRSign(ctx context.Context, csrPEM []byte, saToken string, | ||
certValidTTLInSec int64) ([]string /*PEM-encoded certificate chain*/, error) { | ||
token, err := loginVaultK8sAuthMethod(c.client, c.vaultLoginPath, c.vaultLoginRole, saToken) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we cache the token so we don't need to log in every time when CSRSign is called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No caching the tokens for the following reasons:
- The tokens may expire or be revoked.
- The cached tokens may be leaked.
- The code is simpler when no caching.
- The code is stateless when no caching, as opposed to stateful when caching.
- The storage overhead of caching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do this for simplicity.
return nil, fmt.Errorf("failed to login Vault: %v", err) | ||
} | ||
c.client.SetToken(token) | ||
_, certChain, err := signCsrByVault(c.client, c.vaultSignCsrPath, certValidTTLInSec, csrPEM) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you return the first item if it's not used? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed signCsrByVault() to not return the first item.
|
||
if len(certChain) <= 1 { | ||
log.Errorf("certificate chain length is %d, expected more than 1", len(certChain)) | ||
return nil, fmt.Errorf("invalid cert. chain in the response") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "cert. chain" --> "cert chain"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: changed to "certificate chain".
|
||
// NewMockVaultServer creates a mock Vault server for testing purpose. | ||
// token: required access token | ||
func NewMockVaultServer(t *testing.T, tls bool, loginRole, token, loginResp, signResp string) *MockVaultServer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this internal by starting with lowercase letter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
for id, tc := range testCases { | ||
ch := make(chan *MockVaultServer) | ||
go func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In stead of creating the server each time, can you create two servers in the beginning, one with TLS and one without TLS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
58b2149
to
fa07c19
Compare
fa07c19
to
b1fdcb0
Compare
return nil, fmt.Errorf("failed to login Vault: %v", err) | ||
} | ||
c.client.SetToken(token) | ||
certChain, err := signCsrByVault(c.client, c.vaultSignCsrPath, certValidTTLInSec, csrPEM) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
csr doesn't contain identity info(which is only available in saToken), both google ca and citadel extract identity from saToken, will vault support the same logic ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is up to Vault provider. Will sync up offline on this comment.
@@ -48,6 +50,9 @@ func NewCAClient(endpoint, CAProviderName string, tlsFlag bool) (caClientInterfa | |||
switch CAProviderName { | |||
case googleCAName: | |||
return gca.NewGoogleCAClient(endpoint, tlsFlag) | |||
case vaultCAName1: | |||
//TO-DO (lei-tang): fill vault parameters from environmental variables | |||
return vault.NewVaultClient(tlsFlag, nil, "vaultAddr", "vaultLoginRole", "vaultLoginPath", "vaultSignCsrPath") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is ubuntu CA bundle is good enough to call vault, or do you plan to pass some other tlsRootCert here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CA bundle should be good enough; details are TBD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please enable uses to set "vaultAddr" and "vaultLoginRole" through flags.
Does it make sense to make "vualtLoginPath" and "vaultSignCsrPath" static?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flags have been added. According to the document, all these configs should be read from environmental variables.
return nil, fmt.Errorf("failed to post to %v: %v", csrSigningPath, err) | ||
} | ||
if res == nil { | ||
log.Errorf("sign response is nil") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Error, here and below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/test e2e-simpleTests |
/test istio-pilot-multicluster-e2e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work! Generally looks good to me. Some small comments. Good to go after you fix them.
f212a88
to
0f0fa0c
Compare
0f0fa0c
to
0a47c84
Compare
@lei-tang: The following test failed, say
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: lei-tang, myidpt The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@@ -44,10 +46,13 @@ type configMap interface { | |||
} | |||
|
|||
// NewCAClient create an CA client. | |||
func NewCAClient(endpoint, CAProviderName string, tlsFlag bool) (caClientInterface.Client, error) { | |||
func NewCAClient(endpoint, CAProviderName string, tlsFlag bool, vaultAddr, vaultRole, | |||
vaultAuthPath, vaultSignCsrPath string) (caClientInterface.Client, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't pass vault specific params in this func, better to get those env variable in vault client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting the CA provider inside vault client has pros and cons.
- Pros: less perimeters.
- Cons: CA provider is not exposed at Node Agent. The code is difficult to understand because how the CA provider is configured is hidden somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
those variables are CA provider specific, since we already passed CAProviderName
as input param, setting those variables should be pushed to lower layer(each plugin). let's revisit this after e2e works.
@@ -62,6 +62,18 @@ type Options struct { | |||
|
|||
// PluginNames is plugins' name for certain authentication provider. | |||
PluginNames []string | |||
|
|||
// The Vault CA address. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, move those vault specific param to vault client
Istio CA integrates with Vault CA providers
This PR is for the following issues: