func (pa *PolicyAction) ShortString() string {
	out := []byte{}
	for i, v := range policyActionStrings {
		if (1<<uint(i))&byte(*pa) > 0 {
			out = append(out, v[0])
		} else {
			out = append(out, '-')
		}
	}
	return string(out)
}
ShortString displays a single character representation of each of the
policy's actions.
package primitive
import (
	"encoding/json"
	"errors"
	"strings"
	"time"
	"github.com/manifoldco/go-base64"
	"github.com/manifoldco/torus-cli/identity"
	"github.com/manifoldco/torus-cli/pathexp"
)
type v1Schema struct{}
func (v1Schema) Version() int {
	return 1
}
type immutable struct{}
func (immutable) Immutable() {}
type mutable struct{}
func (mutable) Mutable() {}
type v2Schema struct{}
func (v2Schema) Version() int {
	return 2
}
type LoginPublicKey struct {
	Alg   string        `json:"alg"`
	Salt  *base64.Value `json:"salt"`
	Value *base64.Value `json:"value"`
}
type BaseUser struct {
	mutable
	Username string        `json:"username"`
	Name     string        `json:"name"`
	Email    string        `json:"email"`
	State    string        `json:"state"`
	Password *UserPassword `json:"password"`
	Master   *MasterKey    `json:"master"`
}
type User struct {  
	v2Schema
	BaseUser
	PublicKey *LoginPublicKey `json:"public_key"`
}
type UserV1 struct {  
	v1Schema
	BaseUser
}
type MasterKey struct {
	Value *base64.Value `json:"value"`
	Alg   string        `json:"alg"`
}
type UserPassword struct {
	Salt  string        `json:"salt"`
	Value *base64.Value `json:"value"`
	Alg   string        `json:"alg"`
}
type TokenType string
const (
	LoginToken TokenType = "login"
	AuthToken  TokenType = "auth"
)
type AuthMechanism string
const (
	HMACAuth         AuthMechanism = "hmac"
	EdDSAAuth        AuthMechanism = "eddsa"
	UpgradeEdDSAAuth AuthMechanism = "upgrade-eddsa"
)
type Token struct {  
	v2Schema
	mutable
	TokenType TokenType     `json:"type"`
	Token     string        `json:"token"`
	OwnerID   *identity.ID  `json:"owner_id"`
	Mechanism AuthMechanism `json:"mechanism"`
}
type Signature struct {
	Algorithm   string        `json:"alg"`
	PublicKeyID *identity.ID  `json:"public_key_id"`
	Value       *base64.Value `json:"value"`
}
type PrivateKeyValue struct {
	Algorithm string        `json:"alg"`
	Value     *base64.Value `json:"value"`
}
type PrivateKey struct {  
	v1Schema
	immutable
	Key         PrivateKeyValue `json:"key"`
	OrgID       *identity.ID    `json:"org_id"`
	OwnerID     *identity.ID    `json:"owner_id"`
	PNonce      *base64.Value   `json:"pnonce"`
	PublicKeyID *identity.ID    `json:"public_key_id"`
}
type PublicKeyValue struct {
	Value *base64.Value `json:"value"`
}
type KeyType string
const (
	EncryptionKeyType KeyType = "encryption"
	SigningKeyType    KeyType = "signing"
)
type PublicKey struct {  
	v1Schema
	immutable
	Algorithm string         `json:"alg"`
	Created   time.Time      `json:"created_at"`
	Expires   time.Time      `json:"expires_at"`
	Key       PublicKeyValue `json:"key"`
	OrgID     *identity.ID   `json:"org_id"`
	OwnerID   *identity.ID   `json:"owner_id"`
	KeyType   KeyType        `json:"type"`
}
type ClaimType string
const (
	SignatureClaimType  ClaimType = "signature"
	RevocationClaimType ClaimType = "revocation"
)
type Claim struct {  
	v1Schema
	immutable
	Created     time.Time    `json:"created_at"`
	OrgID       *identity.ID `json:"org_id"`
	OwnerID     *identity.ID `json:"owner_id"`
	Previous    *identity.ID `json:"previous"`
	PublicKeyID *identity.ID `json:"public_key_id"`
	ClaimType   ClaimType    `json:"type"`
}
func NewClaim(orgID, ownerID, previous, pubKeyID *identity.ID, claimType ClaimType) *Claim {
	return &Claim{
		OrgID:       orgID,
		OwnerID:     ownerID,
		Previous:    previous,
		PublicKeyID: pubKeyID,
		ClaimType:   claimType,
		Created:     time.Now().UTC(),
	}
}
type Credential struct {  
	v2Schema
	immutable
	BaseCredential
	State *string `json:"state"`
}
type CredentialV1 struct {  
	v1Schema
	immutable
	BaseCredential
}
type BaseCredential struct {
	Credential        *CredentialValue `json:"credential"`
	KeyringID         *identity.ID     `json:"keyring_id"`
	Name              string           `json:"name"`
	Nonce             *base64.Value    `json:"nonce"`
	OrgID             *identity.ID     `json:"org_id"`
	PathExp           *pathexp.PathExp `json:"pathexp"`
	Previous          *identity.ID     `json:"previous"`
	ProjectID         *identity.ID     `json:"project_id"`
	CredentialVersion int              `json:"version"`
}
type CredentialValue struct {
	Algorithm string        `json:"alg"`
	Nonce     *base64.Value `json:"nonce"`
	Value     *base64.Value `json:"value"`
}
type BaseKeyring struct {
	immutable
	Created        time.Time        `json:"created_at"`
	OrgID          *identity.ID     `json:"org_id"`
	PathExp        *pathexp.PathExp `json:"pathexp"`
	Previous       *identity.ID     `json:"previous"`
	ProjectID      *identity.ID     `json:"project_id"`
	KeyringVersion int              `json:"version"`
}
type KeyringV1 struct {  
	v1Schema
	BaseKeyring
}
type Keyring struct {  
	v2Schema
	BaseKeyring
}
func NewKeyring(orgID, projectID *identity.ID, pathExp *pathexp.PathExp) *Keyring {
	return &Keyring{
		BaseKeyring: BaseKeyring{
			Created:   time.Now().UTC(),
			OrgID:     orgID,
			PathExp:   pathExp,
			ProjectID: projectID,
			Previous:       nil,
			KeyringVersion: 1,
		},
	}
}
type KeyringMemberV1 struct {  
	v1Schema
	immutable
	Created         time.Time         `json:"created_at"`
	EncryptingKeyID *identity.ID      `json:"encrypting_key_id"`
	Key             *KeyringMemberKey `json:"key"`
	KeyringID       *identity.ID      `json:"keyring_id"`
	OrgID           *identity.ID      `json:"org_id"`
	OwnerID         *identity.ID      `json:"owner_id"`
	ProjectID       *identity.ID      `json:"project_id"`
	PublicKeyID     *identity.ID      `json:"public_key_id"`
}
type KeyringMember struct {  
	v2Schema
	immutable
	Created         time.Time    `json:"created_at"`
	EncryptingKeyID *identity.ID `json:"encrypting_key_id"`
	KeyringID       *identity.ID `json:"keyring_id"`
	OrgID           *identity.ID `json:"org_id"`
	OwnerID         *identity.ID `json:"owner_id"`
	PublicKeyID     *identity.ID `json:"public_key_id"`
}
type KeyringMemberKey struct {
	Algorithm string        `json:"alg"`
	Nonce     *base64.Value `json:"nonce"`
	Value     *base64.Value `json:"value"`
}
type MEKShare struct {  
	v1Schema
	immutable
	Created         time.Time         `json:"created_at"`
	OrgID           *identity.ID      `json:"org_id"`
	OwnerID         *identity.ID      `json:"owner_id"`
	KeyringID       *identity.ID      `json:"keyring_id"`
	KeyringMemberID *identity.ID      `json:"keyring_member_id"`
	Key             *KeyringMemberKey `json:"key"`
}
type KeyringMemberClaim struct {  
	v1Schema
	immutable
	OrgID           *identity.ID              `json:"org_id"`
	KeyringID       *identity.ID              `json:"keyring_id"`
	KeyringMemberID *identity.ID              `json:"keyring_member_id"`
	OwnerID         *identity.ID              `json:"owner_id"`
	Previous        *identity.ID              `json:"previous"`
	ClaimType       ClaimType                 `json:"type"`
	Reason          *KeyringMemberClaimReason `json:"reason"`
	Created         time.Time                 `json:"created_at"`
}
type KeyringMemberClaimReason struct {
	Type   KeyringMemberRevocationType   `json:"type"`
	Params KeyringMemberRevocationParams `json:"params"`
}
func (k *KeyringMemberClaimReason) UnmarshalJSON(b []byte) error {
	raw := struct {
		Type   KeyringMemberRevocationType `json:"type"`
		Params json.RawMessage             `json:"params"`
	}{}
	err := json.Unmarshal(b, &raw)
	if err != nil {
		return err
	}
	k.Type = raw.Type
	switch k.Type {
	case OrgRemovalRevocationType:  
		return nil
	case KeyRevocationRevocationType:
		k.Params = &KeyRevocationRevocationParams{}
	case MachineDestroyRevocationType:
		k.Params = &MachineDestroyRevocationParams{}
	case MachineTokenDestroyRevocationType:
		k.Params = &MachineTokenDestroyRevocationParams{}
	}
	return json.Unmarshal(raw.Params, k.Params)
}
type KeyringMemberRevocationType byte
const (
	OrgRemovalRevocationType KeyringMemberRevocationType = iota
	KeyRevocationRevocationType
	MachineDestroyRevocationType
	MachineTokenDestroyRevocationType
)
func (k KeyringMemberRevocationType) String() string {
	switch k {
	case OrgRemovalRevocationType:
		return "org_removal"
	case KeyRevocationRevocationType:
		return "key_revocation"
	case MachineDestroyRevocationType:
		return "machine_destroy"
	case MachineTokenDestroyRevocationType:
		return "machine_token_destroy"
	default:
		panic("invalid revocation type value")
	}
}
func (k KeyringMemberRevocationType) MarshalText() ([]byte, error) {
	return []byte(k.String()), nil
}
var errBadRevocationType = errors.New("unknown revocation type")
func (k *KeyringMemberRevocationType) UnmarshalText(b []byte) error {
	switch string(b) {
	case "org_removal":
		*k = OrgRemovalRevocationType
	case "key_revocation":
		*k = KeyRevocationRevocationType
	case "machine_destroy":
		*k = MachineDestroyRevocationType
	case "machine_token_destroy":
		*k = MachineTokenDestroyRevocationType
	default:
		return errBadRevocationType
	}
	return nil
}
type KeyringMemberRevocationParams interface{}
type KeyRevocationRevocationParams struct {
	PublicKeyID *identity.ID `json:"public_key_id"`
}
type MachineDestroyRevocationParams struct {
	MachineID *identity.ID `json:"machine_id"`
}
type MachineTokenDestroyRevocationParams struct {
	MachineTokenID *identity.ID `json:"machine_token_id"`
}
type Org struct {  
	v1Schema
	mutable
	Name string `json:"name"`
}
const (
	OrgInvitePendingState    = "pending"
	OrgInviteAssociatedState = "associated"
	OrgInviteAcceptedState   = "accepted"
	OrgInviteApprovedState   = "approved"
)
type OrgInvite struct {  
	v1Schema
	mutable
	OrgID      *identity.ID `json:"org_id"`
	Email      string       `json:"email"`
	InviterID  *identity.ID `json:"inviter_id"`
	InviteeID  *identity.ID `json:"invitee_id"`
	ApproverID *identity.ID `json:"approver_id"`
	State      string       `json:"state"`
	Code       *struct {
		Alg   string        `json:"alg"`
		Salt  *base64.Value `json:"salt"`
		Value *base64.Value `json:"value"`
	} `json:"code"`
	PendingTeams []identity.ID `json:"pending_teams"`
	Created      *time.Time    `json:"created_at"`
	Accepted     *time.Time    `json:"accepted_at"`
	Approved     *time.Time    `json:"approved_at"`
}
const (
	MachineActiveState    = "active"
	MachineDestroyedState = "destroyed"
)
type Machine struct {  
	v1Schema
	mutable
	Name        string       `json:"name"`
	OrgID       *identity.ID `json:"org_id"`
	CreatedBy   *identity.ID `json:"created_by"`
	Created     time.Time    `json:"created_at"`
	DestroyedBy *identity.ID `json:"destroyed_by"`
	Destroyed   *time.Time   `json:"destroyed_at"`
	State       string       `json:"state"`
}
const (
	MachineTokenActiveState    = "active"
	MachineTokenDestroyedState = "destroyed"
)
type MachineToken struct {  
	v1Schema
	mutable
	OrgID       *identity.ID    `json:"org_id"`
	MachineID   *identity.ID    `json:"machine_id"`
	PublicKey   *LoginPublicKey `json:"public_key"`
	Master      *MasterKey      `json:"master"`
	CreatedBy   *identity.ID    `json:"created_by"`
	Created     time.Time       `json:"created_at"`
	DestroyedBy *identity.ID    `json:"destroyed_by"`
	Destroyed   *time.Time      `json:"destroyed_at"`
	State       string          `json:"state"`
}
type Project struct {  
	v1Schema
	mutable
	Name  string       `json:"name"`
	OrgID *identity.ID `json:"org_id"`
}
type Policy struct {  
	v1Schema
	mutable
	PolicyType string       `json:"type"`
	Previous   *identity.ID `json:"previous"`
	OrgID      *identity.ID `json:"org_id"`
	Policy     struct {
		Name        string            `json:"name"`
		Description string            `json:"description"`
		Statements  []PolicyStatement `json:"statements"`
	} `json:"policy"`
}
type PolicyStatement struct {
	Effect   PolicyEffect `json:"effect"`
	Action   PolicyAction `json:"action"`
	Resource string       `json:"resource"`
}
type PolicyEffect bool
const (
	PolicyEffectAllow = true
	PolicyEffectDeny  = false
)
func (pe *PolicyEffect) MarshalText() ([]byte, error) {
	if *pe {
		return []byte("allow"), nil
	}
	return []byte("deny"), nil
}
func (pe *PolicyEffect) UnmarshalText(b []byte) error {
	*pe = string(b) == "allow" || string(b) == "sudo"
	return nil
}
func (pe *PolicyEffect) String() string {
	b, _ := pe.MarshalText()
	return string(b)
}
type PolicyAction byte
const (
	PolicyActionCreate = 1 << iota
	PolicyActionRead
	PolicyActionUpdate
	PolicyActionDelete
	PolicyActionList
)
var policyActionStrings = []string{
	"create",
	"read",
	"update",
	"delete",
	"list",
}
func (pa *PolicyAction) MarshalJSON() ([]byte, error) {
	out := []string{}
	for i, v := range policyActionStrings {
		if (1<<uint(i))&byte(*pa) > 0 {
			out = append(out, v)
		}
	}
	if len(out) == 1 {
		return json.Marshal(out[0])
	}
	return json.Marshal(out)
}
func (pa *PolicyAction) UnmarshalJSON(b []byte) error {
	raw := make([]string, 1)
	var err error
	if len(b) > 0 && b[0] == '"' {
		err = json.Unmarshal(b, &raw[0])
	} else {
		err = json.Unmarshal(b, &raw)
	}
	if err != nil {
		return err
	}
	for _, a := range raw {
		for i, v := range policyActionStrings {
			if a == v {
				*pa |= 1 << uint(i)
				continue
			}
		}
	}
	return nil
}
func (pa *PolicyAction) String() string {
	out := []string{}
	for i, v := range policyActionStrings {
		if (1<<uint(i))&byte(*pa) > 0 {
			out = append(out, v)
		}
	}
	return strings.Join(out, ", ")
}