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

Login MFA #14025

Merged
merged 13 commits into from
Feb 17, 2022
Merged

Login MFA #14025

merged 13 commits into from
Feb 17, 2022

Conversation

raskchanky
Copy link
Contributor

return false, nil
}

func (b *SystemBackend) mfaPaths() []*framework.Path {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this might need to be on ENT side only

}
}

func (c *Core) PersistTOTPKey(ctx context.Context, methodID, entityID, key string) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is redefined in identity_store_oss.go as well.

return nil
}

func mfaConfigTableSchema() *memdb.TableSchema {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this also belongs to ENT?

if namespaceId == namespace.RootNamespaceID {
barrierView = b.Core.systemBarrierView
} else {
barrierView = b.Core.nsView.SubView(path.Join(namespaceId, systemBarrierPrefix) + "/")
Copy link
Contributor

Choose a reason for hiding this comment

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

in OSS, there seems to be no b.Core.nsView. So, maybe barrierViewForNamespace would need to have different functionality in OSS and ENT?

// that NS or its children
//- an entity may configure TOTP keys for methods defined in the entity's NS or
// its parents
func TestNamespaceLoginMfaTotp(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This test belong to ENT side

Core: core,
db: db,
logger: logger,
mfaBackend: NewPolicyMFABackend(core, logger),
Copy link
Contributor

Choose a reason for hiding this comment

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

NewPolicyMFABackend needs to be defined in OSS as well. Currently, this is only defined in ENT in policy_mfa_ent.go
Also, not sure if NewSystemBackend should even configure mfaBackend this way. Maybe, configuring the mfa part should be done in an ENT specific module?

Core *Core
db *memdb.MemDB
logger log.Logger
mfaBackend *PolicyMFABackend
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be something generic like MFABackend?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ncabatoff did the split between PolicyMFABackend and LoginMFABackend, but I think this is correct to stay as it is, because the existing enterprise MFA functionality that uses the system backend is policy MFA.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well in OSS, we don't support PolicyMFABackend. Keeping this as is would not resolve in OSS as PolicyMFABackend is defined policy_mfa_ent.go right now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yes, of course.

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 could probably setup something similar to how the Core struct hides enterprise specific fields. https://github.com/hashicorp/vault-enterprise/blob/main/vault/core.go#L199

@hghaf099
Copy link
Contributor

It seems that we would need to run go mod tidy as well. +github.com/dgrijalva/jwt-go is not included in go.sum for some reason.

// login MFA. The following paths are supported:
// mfa/method-id/:mfa_method - management of MFA method IDs, which can be used for configuration
// mfa/login_enforcement/:config_name - configures single or two phase MFA auth
func (b *SystemBackend) loginMFAPaths() []*framework.Path {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not hooked right now as far as I could tell. Should it be added here?

b.Backend.Paths = append(b.Backend.Paths, entPaths(b)...)
b.Backend.Paths = append(b.Backend.Paths, b.configPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.rekeyPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.sealPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.statusPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.pluginsCatalogListPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.pluginsCatalogCRUDPath())
b.Backend.Paths = append(b.Backend.Paths, b.pluginsReloadPath())
b.Backend.Paths = append(b.Backend.Paths, b.auditPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.mountPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.authPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.leasePaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.policyPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.wrappingPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.toolsPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.capabilitiesPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.internalPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.pprofPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.remountPath())
b.Backend.Paths = append(b.Backend.Paths, b.metricsPath())
b.Backend.Paths = append(b.Backend.Paths, b.monitorPath())
b.Backend.Paths = append(b.Backend.Paths, b.inFlightRequestPath())
b.Backend.Paths = append(b.Backend.Paths, b.hostInfoPath())
b.Backend.Paths = append(b.Backend.Paths, b.quotasPaths()...)
b.Backend.Paths = append(b.Backend.Paths, b.rootActivityPaths()...)

RequestNSPath: ns.Path,
RequestConnRemoteAddr: req.Connection.RemoteAddr, // this is needed for the DUO method
TimeOfStorage: time.Now(),
RequestID: req.ID,
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be mfaRequestID?

@vercel vercel bot temporarily deployed to Preview – vault February 16, 2022 18:37 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 16, 2022 18:37 Inactive
* Delete an MFA methodID only if it is not used by an MFA enforcement config

* Fixing a bug: mfa/validate is an unauthenticated path, and goes through the handleLoginRequest path
@vercel vercel bot temporarily deployed to Preview – vault February 16, 2022 18:39 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 16, 2022 18:39 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 16, 2022 18:45 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 16, 2022 18:45 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 16, 2022 19:27 Inactive
* preventing replay attack on MFA passcodes

* using %w instead of %s for error
@vercel vercel bot temporarily deployed to Preview – vault February 16, 2022 19:28 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 16, 2022 19:36 Inactive
CLI prints a warning message indicating the login request needs to get validated
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 16, 2022 19:52 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 16, 2022 19:52 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 16, 2022 23:30 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 16, 2022 23:30 Inactive
Copy link
Contributor

@hghaf099 hghaf099 left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Collaborator

@ncabatoff ncabatoff left a comment

Choose a reason for hiding this comment

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

Minor comments, nice work!

command/write.go Outdated
@@ -146,6 +146,11 @@ func (c *WriteCommand) Run(args []string) int {
return 0
}

if secret != nil && secret.Auth != nil && secret.Auth.MFARequirement != nil {
c.UI.Warn(wrapAtLength("WARNING! A login request was issued that is subject to "+
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think all-caps "WARNING" may be a little too strong. I'd leave it as a UI.Warn but drop the "WARNING" since it's really more informative - like if someone is doing this routinely I think it makes this a bit more alarming than it needs to be.


func (c *Core) barrierViewForNamespace(namespaceId string) (*BarrierView, error) {
if namespaceId != namespace.RootNamespaceID {
return nil, fmt.Errorf("faild to find barrier view for non-root namespace")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return nil, fmt.Errorf("faild to find barrier view for non-root namespace")
return nil, fmt.Errorf("failed to find barrier view for non-root namespace")

// going to return early before generating the token
// the user receives the mfaRequirement, and need to use the
// login MFA validate endpoint to get the token
return resp, auth, retErr
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return resp, auth, retErr
return resp, auth, nil

retErr should only be non-nil if an error occurred earlier, in which case we'd have already returned.

@vercel vercel bot temporarily deployed to Preview – vault-storybook February 17, 2022 18:15 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 17, 2022 18:15 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 17, 2022 18:36 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 17, 2022 18:36 Inactive
@@ -0,0 +1,3 @@
```release-note:feature
Copy link
Collaborator

Choose a reason for hiding this comment

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

@raskchanky Catching this in final changelog review, but as a feature this should have the "new feature" formatting, which is on the changelog page on the wiki.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Argh, sorry 😞 . I can submit a PR to change it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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

4 participants