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

Istio Citadel Agent integrates with Vault CA providers #10638

Merged
merged 10 commits into from
Jan 1, 2019

Conversation

lei-tang
Copy link
Contributor

@lei-tang lei-tang commented Dec 22, 2018

Istio CA integrates with Vault CA providers

This PR is for the following issues:

@lei-tang lei-tang force-pushed the vault_integ_release_1.1 branch 3 times, most recently from fa237ee to 2e017ad Compare December 24, 2018 09:55
@lei-tang lei-tang force-pushed the vault_integ_release_1.1 branch 2 times, most recently from f17c8bc to c55e0f1 Compare December 24, 2018 14:26
)

const (
googleCAName = "GoogleCA"
citadelName = "Citadel"
vaultCAName1 = "VaultCA1"
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove 1.

Copy link
Contributor Author

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,
Copy link
Contributor

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?

Copy link
Contributor Author

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)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: createVaultTLSClient

Copy link
Contributor Author

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)
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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)
Copy link
Contributor

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? :)

Copy link
Contributor Author

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")
Copy link
Contributor

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"

Copy link
Contributor Author

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 {
Copy link
Contributor

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?

Copy link
Contributor Author

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() {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@lei-tang lei-tang force-pushed the vault_integ_release_1.1 branch 2 times, most recently from 58b2149 to fa07c19 Compare December 27, 2018 10:18
return nil, fmt.Errorf("failed to login Vault: %v", err)
}
c.client.SetToken(token)
certChain, err := signCsrByVault(c.client, c.vaultSignCsrPath, certValidTTLInSec, csrPEM)
Copy link
Contributor

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 ?

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 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")
Copy link
Contributor

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 ?

Copy link
Contributor Author

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.

Copy link
Contributor

@myidpt myidpt Dec 31, 2018

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?

Copy link
Contributor Author

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")
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@lei-tang lei-tang changed the title [Work-in-progress] Istio CA integrates with Vault CA providers Istio CA integrates with Vault CA providers Dec 31, 2018
@lei-tang
Copy link
Contributor Author

/test e2e-simpleTests

@lei-tang
Copy link
Contributor Author

/test istio-pilot-multicluster-e2e

Copy link
Contributor

@myidpt myidpt left a 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.

@istio-testing
Copy link
Collaborator

@lei-tang: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
prow/istio-pilot-multicluster-e2e.sh 0a47c84 link /test istio-pilot-multicluster-e2e

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.

@myidpt
Copy link
Contributor

myidpt commented Jan 1, 2019

/lgtm
/approve
Thanks for the work!

@istio-testing
Copy link
Collaborator

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@istio-testing istio-testing merged commit f97a89f into istio:release-1.1 Jan 1, 2019
@myidpt myidpt changed the title Istio CA integrates with Vault CA providers Istio Citadel Agent integrates with Vault CA providers Jan 1, 2019
@@ -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) {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.
Copy link
Contributor

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

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.

None yet

6 participants