// handleCreateAgainstRole handles the auth/token/create path for a role
963051
func (ts *TokenStore) handleCreateAgainstRole(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := d.Get("role_name").(string)
	roleEntry, err := ts.tokenStoreRole(ctx, name)
	if err != nil {
		return nil, err
	}
	if roleEntry == nil {
		return logical.ErrorResponse(fmt.Sprintf("unknown role %s", name)), nil
	}

	return ts.handleCreateCommon(ctx, req, d, false, roleEntry)
}
541579
func NewRole(name RoleName, threshold int, keyIDs, paths []string) (*Role, error) {
	if IsDelegation(name) {
		if len(paths) == 0 {
			logrus.Debugf("role %s with no Paths will never be able to publish content until one or more are added", name)
		}
	}
	if threshold < 1 {
		return nil, ErrInvalidRole{Role: name}
	}
	if !ValidRole(name) {
		return nil, ErrInvalidRole{Role: name}
	}
	return &Role{
		RootRole: RootRole{
			KeyIDs:    keyIDs,
			Threshold: threshold,
		},
		Name:  name,
		Paths: paths,
	}, nil

}
375418
func (b *backend) pathRoleCreateUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	roleName := data.Get("role_name").(string)
	if roleName == "" {
		return logical.ErrorResponse("missing role_name"), nil
	}

	lock := b.roleLock(roleName)
	lock.Lock()
	defer lock.Unlock()

	// Check if the role already exists
	role, err := b.roleEntry(ctx, req.Storage, roleName)
	if err != nil {
		return nil, err
	}

	// Create a new entry object if this is a CreateOperation
	switch {
	case role == nil && req.Operation == logical.CreateOperation:
		hmacKey, err := uuid.GenerateUUID()
		if err != nil {
			return nil, errwrap.Wrapf("failed to create role_id: {{err}}", err)
		}
		role = &roleStorageEntry{
			name:              strings.ToLower(roleName),
			HMACKey:           hmacKey,
			LowerCaseRoleName: true,
		}
	case role == nil:
		return logical.ErrorResponse(fmt.Sprintf("role name %q doesn't exist", roleName)), logical.ErrUnsupportedPath
	}

	localSecretIDsRaw, ok := data.GetOk("local_secret_ids")
	if ok {
		switch {
		case req.Operation == logical.CreateOperation:
			localSecretIDs := localSecretIDsRaw.(bool)
			if localSecretIDs {
				role.SecretIDPrefix = secretIDLocalPrefix
			}
		default:
			return logical.ErrorResponse("local_secret_ids can only be modified during role creation"), nil
		}
	}

	previousRoleID := role.RoleID
	if roleIDRaw, ok := data.GetOk("role_id"); ok {
		role.RoleID = roleIDRaw.(string)
	} else if req.Operation == logical.CreateOperation {
		roleID, err := uuid.GenerateUUID()
		if err != nil {
			return nil, errwrap.Wrapf("failed to generate role_id: {{err}}", err)
		}
		role.RoleID = roleID
	}
	if role.RoleID == "" {
		return logical.ErrorResponse("invalid role_id supplied, or failed to generate a role_id"), nil
	}

	if bindSecretIDRaw, ok := data.GetOk("bind_secret_id"); ok {
		role.BindSecretID = bindSecretIDRaw.(bool)
	} else if req.Operation == logical.CreateOperation {
		role.BindSecretID = data.Get("bind_secret_id").(bool)
	}

	if boundCIDRListRaw, ok := data.GetFirst("secret_id_bound_cidrs", "bound_cidr_list"); ok {
		role.SecretIDBoundCIDRs = boundCIDRListRaw.([]string)
	}

	if len(role.SecretIDBoundCIDRs) != 0 {
		valid, err := cidrutil.ValidateCIDRListSlice(role.SecretIDBoundCIDRs)
		if err != nil {
			return nil, errwrap.Wrapf("failed to validate CIDR blocks: {{err}}", err)
		}
		if !valid {
			return logical.ErrorResponse("invalid CIDR blocks"), nil
		}
	}

	if boundCIDRListRaw, ok := data.GetOk("token_bound_cidrs"); ok {
		role.TokenBoundCIDRs = boundCIDRListRaw.([]string)
	}

	if len(role.TokenBoundCIDRs) != 0 {
		valid, err := cidrutil.ValidateCIDRListSlice(role.TokenBoundCIDRs)
		if err != nil {
			return nil, errwrap.Wrapf("failed to validate CIDR blocks: {{err}}", err)
		}
		if !valid {
			return logical.ErrorResponse("invalid CIDR blocks"), nil
		}
	}

	if policiesRaw, ok := data.GetOk("policies"); ok {
		role.Policies = policyutil.ParsePolicies(policiesRaw)
	} else if req.Operation == logical.CreateOperation {
		role.Policies = policyutil.ParsePolicies(data.Get("policies"))
	}

	periodRaw, ok := data.GetOk("period")
	if ok {
		role.Period = time.Second * time.Duration(periodRaw.(int))
	} else if req.Operation == logical.CreateOperation {
		role.Period = time.Second * time.Duration(data.Get("period").(int))
	}
	if role.Period > b.System().MaxLeaseTTL() {
		return logical.ErrorResponse(fmt.Sprintf("period of %q is greater than the backend's maximum lease TTL of %q", role.Period.String(), b.System().MaxLeaseTTL().String())), nil
	}

	if secretIDNumUsesRaw, ok := data.GetOk("secret_id_num_uses"); ok {
		role.SecretIDNumUses = secretIDNumUsesRaw.(int)
	} else if req.Operation == logical.CreateOperation {
		role.SecretIDNumUses = data.Get("secret_id_num_uses").(int)
	}
	if role.SecretIDNumUses < 0 {
		return logical.ErrorResponse("secret_id_num_uses cannot be negative"), nil
	}

	if secretIDTTLRaw, ok := data.GetOk("secret_id_ttl"); ok {
		role.SecretIDTTL = time.Second * time.Duration(secretIDTTLRaw.(int))
	} else if req.Operation == logical.CreateOperation {
		role.SecretIDTTL = time.Second * time.Duration(data.Get("secret_id_ttl").(int))
	}

	if tokenNumUsesRaw, ok := data.GetOk("token_num_uses"); ok {
		role.TokenNumUses = tokenNumUsesRaw.(int)
	} else if req.Operation == logical.CreateOperation {
		role.TokenNumUses = data.Get("token_num_uses").(int)
	}
	if role.TokenNumUses < 0 {
		return logical.ErrorResponse("token_num_uses cannot be negative"), nil
	}

	if tokenTTLRaw, ok := data.GetOk("token_ttl"); ok {
		role.TokenTTL = time.Second * time.Duration(tokenTTLRaw.(int))
	} else if req.Operation == logical.CreateOperation {
		role.TokenTTL = time.Second * time.Duration(data.Get("token_ttl").(int))
	}

	if tokenMaxTTLRaw, ok := data.GetOk("token_max_ttl"); ok {
		role.TokenMaxTTL = time.Second * time.Duration(tokenMaxTTLRaw.(int))
	} else if req.Operation == logical.CreateOperation {
		role.TokenMaxTTL = time.Second * time.Duration(data.Get("token_max_ttl").(int))
	}

	tokenType := role.TokenType
	if tokenTypeRaw, ok := data.GetOk("token_type"); ok {
		tokenType = tokenTypeRaw.(string)
		switch tokenType {
		case "":
			tokenType = "default"
		case "service", "batch", "default":
		default:
			return logical.ErrorResponse(fmt.Sprintf("invalid 'token_type' value %q", tokenType)), nil
		}
	} else if req.Operation == logical.CreateOperation {
		tokenType = data.Get("token_type").(string)
	}
	role.TokenType = tokenType

	if role.TokenType == "batch" {
		if role.Period != 0 {
			return logical.ErrorResponse("'token_type' cannot be 'batch' when role is set to generate periodic tokens"), nil
		}
		if role.TokenNumUses != 0 {
			return logical.ErrorResponse("'token_type' cannot be 'batch' when role is set to generate tokens with limited use count"), nil
		}
	}

	// Check that the TokenTTL value provided is less than the TokenMaxTTL.
	// Sanitizing the TTL and MaxTTL is not required now and can be performed
	// at credential issue time.
	if role.TokenMaxTTL > time.Duration(0) && role.TokenTTL > role.TokenMaxTTL {
		return logical.ErrorResponse("token_ttl should not be greater than token_max_ttl"), nil
	}

	var resp *logical.Response
	if role.TokenMaxTTL > b.System().MaxLeaseTTL() {
		resp = &logical.Response{}
		resp.AddWarning("token_max_ttl is greater than the backend mount's maximum TTL value; issued tokens' max TTL value will be truncated")
	}

	// Store the entry.
	return resp, b.setRoleEntry(ctx, req.Storage, role.name, role, previousRoleID)
}
537305
func CreateLease(c *cli.Context) {
	// inspect env for auth env var
	authToken := os.Getenv("AUTH_TOKEN")
	if authToken == "" {
		log.Fatal("An authorization token is required in the form of an env var AUTH_TOKEN")
	}
	server := c.GlobalString("server")
	if server == "" {
		log.Fatal("Server missing")
	}
	durationSec := c.Int("duration")
	if durationSec <= 0 {
		log.Fatalf("Invalid duration %d", durationSec)
	}
	envPrefix := c.String("env-prefix")
	clusterRegex := c.String("cluster-regex")
	clusterVersion := c.String("cluster-version")
	cloudProvider := c.String("provider")
	if cloudProvider == "" {
		log.Fatal("Cloud Provider not provided")
	}
	if cloudProvider == "azure" && clusterVersion != "" {
		log.Fatal("Finding clusters by version is currently not supported with Azure!")
	}

	kcfgFile := c.String("kubeconfig-file")
	if len(kcfgFile) < 1 {
		log.Fatal("Missing kubeconfig-file")
	}

	fd, err := os.Create(kcfgFile)
	if err != nil {
		log.Fatalf("Error opening %s: %s", kcfgFile, err)
	}
	defer fd.Close()

	resp, err := client.CreateLease(server, authToken, cloudProvider, clusterVersion, clusterRegex, durationSec)
	if err != nil {
		log.Fatalf("Error returned from server when creating lease: %s", err)
	}

	kcfg, err := resp.KubeConfigBytes()
	if err != nil {
		log.Fatalf("Error decoding kubeconfig: %s", err)
	}
	fmt.Println(exportVar(envPrefix, ipEnvVarName, resp.IP))
	fmt.Println(exportVar(envPrefix, tokenEnvVarName, resp.Token))
	fmt.Println(exportVar(envPrefix, clusterNameEnvVarName, resp.ClusterName))

	if _, err := io.Copy(fd, bytes.NewBuffer(kcfg)); err != nil {
		log.Fatalf("Error writing new Kubeconfig file to %s: %s", kcfgFile, err)
	}
}
438491
func (s *Server) AccessTokensCreate(token *AccessToken) (*AccessToken, error) {
	signed, err := signToken(s.Secret, token)
	if err != nil {
		return token, err
	}

	token.Token = signed

	return token, token.IsValid()
}
1232868
func CreateUserAndRoleWithoutRoles(clt clt, username string, allowedLogins []string) (services.User, services.Role, error) {
	user, err := services.NewUser(username)
	if err != nil {
		return nil, nil, trace.Wrap(err)
	}

	role := services.RoleForUser(user)
	set := services.MakeRuleSet(role.GetRules(services.Allow))
	delete(set, services.KindRole)
	role.SetRules(services.Allow, set.Slice())
	role.SetLogins(services.Allow, []string{user.GetName()})
	err = clt.UpsertRole(role)
	if err != nil {
		return nil, nil, trace.Wrap(err)
	}

	user.AddRole(role.GetName())
	err = clt.UpsertUser(user)
	if err != nil {
		return nil, nil, trace.Wrap(err)
	}

	return user, role, nil
}
939016
func (cs *CryptoService) Create(role data.RoleName, gun data.GUN, algorithm string) (data.PublicKey, error) {
	if algorithm == data.RSAKey {
		return nil, fmt.Errorf("%s keys can only be imported", data.RSAKey)
	}

	privKey, err := utils.GenerateKey(algorithm)
	if err != nil {
		return nil, fmt.Errorf("failed to generate %s key: %v", algorithm, err)
	}
	logrus.Debugf("generated new %s key for role: %s and keyID: %s", algorithm, role.String(), privKey.ID())
	pubKey := data.PublicKeyFromPrivate(privKey)

	return pubKey, cs.AddKey(role, gun, privKey)
}
73359
func (b *backend) pathRoleSecretIDList(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	roleName := data.Get("role_name").(string)
	if roleName == "" {
		return logical.ErrorResponse("missing role_name"), nil
	}

	lock := b.roleLock(roleName)
	lock.RLock()
	defer lock.RUnlock()

	// Get the role entry
	role, err := b.roleEntry(ctx, req.Storage, roleName)
	if err != nil {
		return nil, err
	}
	if role == nil {
		return logical.ErrorResponse(fmt.Sprintf("role %q does not exist", roleName)), nil
	}

	// Guard the list operation with an outer lock
	b.secretIDListingLock.RLock()
	defer b.secretIDListingLock.RUnlock()

	roleNameHMAC, err := createHMAC(role.HMACKey, role.name)
	if err != nil {
		return nil, errwrap.Wrapf("failed to create HMAC of role_name: {{err}}", err)
	}

	// Listing works one level at a time. Get the first level of data
	// which could then be used to get the actual SecretID storage entries.
	secretIDHMACs, err := req.Storage.List(ctx, fmt.Sprintf("%s%s/", role.SecretIDPrefix, roleNameHMAC))
	if err != nil {
		return nil, err
	}

	var listItems []string
	for _, secretIDHMAC := range secretIDHMACs {
		// For sanity
		if secretIDHMAC == "" {
			continue
		}

		// Prepare the full index of the SecretIDs.
		entryIndex := fmt.Sprintf("%s%s/%s", role.SecretIDPrefix, roleNameHMAC, secretIDHMAC)

		// SecretID locks are not indexed by SecretIDs itself.
		// This is because SecretIDs are not stored in plaintext
		// form anywhere in the backend, and hence accessing its
		// corresponding lock many times using SecretIDs is not
		// possible. Also, indexing it everywhere using secretIDHMACs
		// makes listing operation easier.
		secretIDLock := b.secretIDLock(secretIDHMAC)

		secretIDLock.RLock()

		result := secretIDStorageEntry{}
		if entry, err := req.Storage.Get(ctx, entryIndex); err != nil {
			secretIDLock.RUnlock()
			return nil, err
		} else if entry == nil {
			secretIDLock.RUnlock()
			return nil, fmt.Errorf("storage entry for SecretID is present but no content found at the index")
		} else if err := entry.DecodeJSON(&result); err != nil {
			secretIDLock.RUnlock()
			return nil, err
		}
		listItems = append(listItems, result.SecretIDAccessor)
		secretIDLock.RUnlock()
	}

	return logical.ListResponse(listItems), nil
}
974384
func MakeHandler(validpath *regexp.Regexp, parser Json2dataConverter, handler HttpHandler, mustHaveInputData bool) http.HandlerFunc {

	return func(w http.ResponseWriter, r *http.Request) {

		// check path
		m := validpath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}

		// handle OPTIONS request
		if r.Method == "OPTIONS" {
			setDefaultHeaders(w)
			return
		}

		// skip other methods
		if r.Method != "POST" && r.Method != "GET" {
			return
		}

		// set access and return type
		origin := r.Header.Get("Origin")
		w.Header().Set("Access-Control-Allow-Origin", origin)
		w.Header().Set("Content-Type", "application/json")

		// handle POST
		var dat []byte
		var err error
		if r.Method == "POST" {
			dat, err = ioutil.ReadAll(r.Body) // parse 'body'
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		}

		// handle GET
		if r.Method == "GET" {
			err = r.ParseForm()
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			for str, _ := range r.Form {
				dat = []byte(str)
				break
			}
		}

		// parse json and call handler
		d := parser(dat)
		if d == nil && mustHaveInputData {
			http.Error(w, "handlermaker.go: parser failed: data is <nil>", http.StatusInternalServerError)
			return
		}
		res, err := handler(w, r, d)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		if res != nil {
			fmt.Fprintf(w, res.String())
		}
	}
}
5718
func NewAuthorizer(access services.Access, identity services.UserGetter, trust services.Trust) (Authorizer, error) {
	if access == nil {
		return nil, trace.BadParameter("missing parameter access")
	}
	if identity == nil {
		return nil, trace.BadParameter("missing parameter identity")
	}
	if trust == nil {
		return nil, trace.BadParameter("missing parameter trust")
	}
	return &authorizer{access: access, identity: identity, trust: trust}, nil
}
1299828
func NewImplicitRole() Role {
	return &RoleV3{
		Kind:    KindRole,
		Version: V3,
		Metadata: Metadata{
			Name:      teleport.DefaultImplicitRole,
			Namespace: defaults.Namespace,
		},
		Spec: RoleSpecV3{
			Options: RoleOptions{
				MaxSessionTTL: MaxDuration(),
			},
			Allow: RoleConditions{
				Namespaces: []string{defaults.Namespace},
				Rules:      CopyRulesSlice(DefaultImplicitRules),
			},
		},
	}
}
198311
func (s *Service) OAuthTokenCreate(ctx context.Context, o OAuthTokenCreateOpts) (*OAuthToken, error) {
	var oauthToken OAuthToken
	return &oauthToken, s.Post(ctx, &oauthToken, fmt.Sprintf("/oauth/tokens"), o)
}
426995
func CreateRule(obj *Rule) error {
	// Validate parameters
	err := ValidateRule(obj)
	if err != nil {
		log.Errorf("ValidateRule retruned error for: %+v. Err: %v", obj, err)
		return err
	}

	// Check if we handle this object
	if objCallbackHandler.RuleCb == nil {
		log.Errorf("No callback registered for rule object")
		return errors.New("Invalid object type")
	}

	saveObj := obj

	collections.ruleMutex.Lock()
	key := collections.rules[obj.Key]
	collections.ruleMutex.Unlock()

	// Check if object already exists
	if key != nil {
		// Perform Update callback
		err = objCallbackHandler.RuleCb.RuleUpdate(collections.rules[obj.Key], obj)
		if err != nil {
			log.Errorf("RuleUpdate retruned error for: %+v. Err: %v", obj, err)
			return err
		}

		// save the original object after update
		collections.ruleMutex.Lock()
		saveObj = collections.rules[obj.Key]
		collections.ruleMutex.Unlock()
	} else {
		// save it in cache
		collections.ruleMutex.Lock()
		collections.rules[obj.Key] = obj
		collections.ruleMutex.Unlock()

		// Perform Create callback
		err = objCallbackHandler.RuleCb.RuleCreate(obj)
		if err != nil {
			log.Errorf("RuleCreate retruned error for: %+v. Err: %v", obj, err)
			collections.ruleMutex.Lock()
			delete(collections.rules, obj.Key)
			collections.ruleMutex.Unlock()
			return err
		}
	}

	// Write it to modeldb
	collections.ruleMutex.Lock()
	err = saveObj.Write()
	collections.ruleMutex.Unlock()
	if err != nil {
		log.Errorf("Error saving rule %s to db. Err: %v", saveObj.Key, err)
		return err
	}

	return nil
}
740241
func (s *NATService) CreateIpForwardingRule(p *CreateIpForwardingRuleParams) (*CreateIpForwardingRuleResponse, error) {
	resp, err := s.cs.newRequest("createIpForwardingRule", p.toURLValues())
	if err != nil {
		return nil, err
	}

	var r CreateIpForwardingRuleResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	// If we have a async client, we need to wait for the async result
	if s.cs.async {
		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
		if err != nil {
			if err == AsyncTimeoutErr {
				return &r, err
			}
			return nil, err
		}

		b, err = getRawValue(b)
		if err != nil {
			return nil, err
		}

		if err := json.Unmarshal(b, &r); err != nil {
			return nil, err
		}
	}

	return &r, nil
}
907897
func BuildHandlerChain(genericConfig *genericapiserver.Config, oauthConfig *osinv1.OAuthConfig, authConfig kubecontrolplanev1.MasterAuthConfig, userAgentMatchingConfig kubecontrolplanev1.UserAgentMatchingConfig, consolePublicURL string) (func(apiHandler http.Handler, kc *genericapiserver.Config) http.Handler, map[string]genericapiserver.PostStartHookFunc, error) {
	// ignore oauthConfig if we have a valid OAuth metadata file
	// this prevents us from running the internal OAuth server when we are honoring an external one
	if oauthMetadataFile := authConfig.OAuthMetadataFile; len(oauthMetadataFile) > 0 {
		if _, _, err := util.LoadOAuthMetadataFile(oauthMetadataFile); err == nil {
			oauthConfig = nil // simplest way to keep existing code paths working
		}
	}

	extraPostStartHooks := map[string]genericapiserver.PostStartHookFunc{}

	var oauthServerHandler http.Handler
	if oauthConfig != nil {
		var newPostStartHooks map[string]genericapiserver.PostStartHookFunc
		var err error
		oauthServerHandler, newPostStartHooks, err = NewOAuthServerHandler(genericConfig, oauthConfig)
		if err != nil {
			return nil, nil, err
		}
		for name, fn := range newPostStartHooks {
			extraPostStartHooks[name] = fn
		}
	}

	return func(apiHandler http.Handler, genericConfig *genericapiserver.Config) http.Handler {
			// these are after the kube handler
			handler := versionSkewFilter(apiHandler, userAgentMatchingConfig)

			// this is the normal kube handler chain
			handler = genericapiserver.DefaultBuildHandlerChain(handler, genericConfig)

			// these handlers are all before the normal kube chain
			handler = translateLegacyScopeImpersonation(handler)
			handler = configprocessing.WithCacheControl(handler, "no-store") // protected endpoints should not be cached

			// redirects from / and /console to consolePublicURL if you're using a browser
			handler = withConsoleRedirect(handler, consolePublicURL)

			if oauthConfig != nil {
				// these handlers are actually separate API servers which have their own handler chains.
				// our server embeds these
				handler = withOAuthRedirection(oauthConfig, handler, oauthServerHandler)
			}

			return handler
		},
		extraPostStartHooks,
		nil
}
264177
func (ts *TokenStore) handleCreateOrphan(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	return ts.handleCreateCommon(ctx, req, d, true, nil)
}
556837
func (b *backend) pathRoleTagUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	roleName := strings.ToLower(data.Get("role").(string))
	if roleName == "" {
		return logical.ErrorResponse("missing role"), nil
	}

	// Fetch the role entry
	roleEntry, err := b.lockedAWSRole(ctx, req.Storage, roleName)
	if err != nil {
		return nil, err
	}
	if roleEntry == nil {
		return logical.ErrorResponse(fmt.Sprintf("entry not found for role %s", roleName)), nil
	}

	// If RoleTag is empty, disallow creation of tag.
	if roleEntry.RoleTag == "" {
		return logical.ErrorResponse("tag creation is not enabled for this role"), nil
	}

	// There should be a HMAC key present in the role entry
	if roleEntry.HMACKey == "" {
		// Not being able to find the HMACKey is an internal error
		return nil, fmt.Errorf("failed to find the HMAC key")
	}

	resp := &logical.Response{}

	// Instance ID is an optional field.
	instanceID := strings.ToLower(data.Get("instance_id").(string))

	// If no policies field was not supplied, then the tag should inherit all the policies
	// on the role. But, it was provided, but set to empty explicitly, only "default" policy
	// should be inherited. So, by leaving the policies var unset to anything when it is not
	// supplied, we ensure that it inherits all the policies on the role.
	var policies []string
	policiesRaw, ok := data.GetOk("policies")
	if ok {
		policies = policyutil.ParsePolicies(policiesRaw)
	}
	if !strutil.StrListSubset(roleEntry.Policies, policies) {
		resp.AddWarning("Policies on the tag are not a subset of the policies set on the role. Login will not be allowed with this tag unless the role policies are updated.")
	}

	// This is an optional field.
	disallowReauthentication := data.Get("disallow_reauthentication").(bool)

	// This is an optional field.
	allowInstanceMigration := data.Get("allow_instance_migration").(bool)
	if allowInstanceMigration && !roleEntry.AllowInstanceMigration {
		resp.AddWarning("Role does not allow instance migration. Login will not be allowed with this tag unless the role value is updated.")
	}

	if disallowReauthentication && allowInstanceMigration {
		return logical.ErrorResponse("cannot set both disallow_reauthentication and allow_instance_migration"), nil
	}

	// max_ttl for the role tag should be less than the max_ttl set on the role.
	maxTTL := time.Duration(data.Get("max_ttl").(int)) * time.Second

	// max_ttl on the tag should not be greater than the system view's max_ttl value.
	if maxTTL > b.System().MaxLeaseTTL() {
		resp.AddWarning(fmt.Sprintf("Given max TTL of %d is greater than the mount maximum of %d seconds, and will be capped at login time.", maxTTL/time.Second, b.System().MaxLeaseTTL()/time.Second))
	}
	// If max_ttl is set for the role, check the bounds for tag's max_ttl value using that.
	if roleEntry.MaxTTL != time.Duration(0) && maxTTL > roleEntry.MaxTTL {
		resp.AddWarning(fmt.Sprintf("Given max TTL of %d is greater than the role maximum of %d seconds, and will be capped at login time.", maxTTL/time.Second, roleEntry.MaxTTL/time.Second))
	}

	if maxTTL < time.Duration(0) {
		return logical.ErrorResponse("max_ttl cannot be negative"), nil
	}

	// Create a random nonce.
	nonce, err := createRoleTagNonce()
	if err != nil {
		return nil, err
	}

	// Create a role tag out of all the information provided.
	rTagValue, err := createRoleTagValue(&roleTag{
		Version:                  roleTagVersion,
		Role:                     roleName,
		Nonce:                    nonce,
		Policies:                 policies,
		MaxTTL:                   maxTTL,
		InstanceID:               instanceID,
		DisallowReauthentication: disallowReauthentication,
		AllowInstanceMigration:   allowInstanceMigration,
	}, roleEntry)
	if err != nil {
		return nil, err
	}

	// Return the key to be used for the tag and the value to be used for that tag key.
	// This key value pair should be set on the EC2 instance.
	resp.Data = map[string]interface{}{
		"tag_key":   roleEntry.RoleTag,
		"tag_value": rTagValue,
	}

	return resp, nil
}