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)
}
UnmarshalJSON implements the json.Unmarshaler interface.
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"`
}