package vault import ( "context" "regexp" "sync" log "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-memdb" "github.com/hashicorp/vault/helper/identity" "github.com/hashicorp/vault/helper/metricsutil" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/storagepacker" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/logical" ) const ( // Storage prefixes entityPrefix = "entity/" ) // metaKeyFormatRegEx checks if a metadata key string is valid var metaKeyFormatRegEx = regexp.MustCompile(`^[a-zA-Z0-9=/+_-]+$`).MatchString const ( // The meta key prefix reserved for Vault's internal use metaKeyReservedPrefix = "vault-" // The maximum number of metadata key pairs allowed to be registered metaMaxKeyPairs = 64 // The maximum allowed length of a metadata key metaKeyMaxLength = 128 // The maximum allowed length of a metadata value metaValueMaxLength = 512 ) // IdentityStore is composed of its own storage view and a MemDB which // maintains active in-memory replicas of the storage contents indexed by // multiple fields. type IdentityStore struct { // IdentityStore is a secret backend in Vault *framework.Backend // view is the storage sub-view where all the artifacts of identity store // gets persisted view logical.Storage // db is the in-memory database where the storage artifacts gets replicated // to enable richer queries based on multiple indexes. db *memdb.MemDB // locks to make sure things are consistent lock sync.RWMutex oidcLock sync.RWMutex // groupLock is used to protect modifications to group entries groupLock sync.RWMutex // oidcCache stores common response data as well as when the periodic func needs // to run. This is conservatively managed, and most writes to the OIDC endpoints // will invalidate the cache. oidcCache *oidcCache // oidcAuthCodeCache stores OIDC authorization codes to be exchanged // for an ID token during an authorization code flow. oidcAuthCodeCache *oidcCache // logger is the server logger copied over from core logger log.Logger // entityPacker is used to pack multiple entity storage entries into 256 // buckets entityPacker *storagepacker.StoragePacker // localAliasPacker is used to pack multiple local alias entries into lesser // storage entries. This is also used to cache entities in the secondary // clusters, those entities which were created by the primary but hasn't // reached secondary via invalidations. localAliasPacker *storagepacker.StoragePacker // groupPacker is used to pack multiple group storage entries into 256 // buckets groupPacker *storagepacker.StoragePacker // disableLowerCaseNames indicates whether or not identity artifacts are // operated case insensitively disableLowerCasedNames bool router *Router redirectAddr string localNode LocalNode namespacer Namespacer metrics metricsutil.Metrics totpPersister TOTPPersister groupUpdater GroupUpdater tokenStorer TokenStorer entityCreator EntityCreator } type groupDiff struct { New []*identity.Group Deleted []*identity.Group Unmodified []*identity.Group } type casesensitivity struct { DisableLowerCasedNames bool `json:"disable_lower_cased_names"` } type LocalNode interface { ReplicationState() consts.ReplicationState HAState() consts.HAState } var _ LocalNode = &Core{} type Namespacer interface { NamespaceByID(context.Context, string) (*namespace.Namespace, error) ListNamespaces() []*namespace.Namespace } var _ Namespacer = &Core{} type TOTPPersister interface { PersistTOTPKey(ctx context.Context, configID string, entityID string, key string) error } var _ TOTPPersister = &Core{} type GroupUpdater interface { SendGroupUpdate(ctx context.Context, group *identity.Group) (bool, error) } var _ GroupUpdater = &Core{} type TokenStorer interface { LookupToken(context.Context, string) (*logical.TokenEntry, error) CreateToken(context.Context, *logical.TokenEntry) error } var _ TokenStorer = &Core{} type EntityCreator interface { CreateEntity(ctx context.Context) (*identity.Entity, error) } var _ EntityCreator = &Core{}