When you issue an asset on Stellar, anyone can hold it by default. In general, that’s a good thing: easy access means better reach and better liquidity, and most of the time, issuers with KYC requirements can handle those when an asset moves onto or off of the network. Most fiat-backed token issuers, for instance, use the transfer server protocol specified in SEP-24 to decide whether to honor deposits and withdrawals rather than setting account-level flags. You can read about how to do that in the Enable Deposit and Withdrawal section.

However, if you need to control access to an asset to comply with regulations (or for any other reason), you can easily do so by enabling flags on your issuing account.

## Flags​

Flags are created on the account level using a set_options operation. They can be set at any time in the life cycle of an asset, not just when you issue it:

### Authorization Required​

When AUTHORIZATION REQUIRED is enabled, an issuer must approve an account before that account can hold its asset. This setting allows issuers to vet potential token holders using whatever means they see fit, and to approve trustlines if and only if the holders pass muster.

To allow access, the user creates a trustline, and the issuer approves it by changing the AUTHORIZE flag with the allow_trust operation.

There are two levels of authorization an asset issuer can grant using the allow_trust operation:

• AUTHORIZED: This flag signifies complete authorization allowing an account to transact freely with the asset to make and receive payments and place orders.
• AUTHORIZED_TO_MAINTAIN_LIABILITIES: This flag denotes limited authorization that allows an account to maintain current orders, but not to otherwise transact with the asset.

### Authorization Revocable​

When AUTHORIZATION_REVOCABLE is enabled, an issuer can revoke an existing trustline's authorization, thereby freezing the asset held by an account. Doing so prevents that account from transfering or trading the asset, and cancels the account’s open orders for the asset.

AUTHORIZATION_REVOCABLE also allows an issuer to reduce authorization from complete to limited, which prevents the account from transferring or trading the asset, but does not cancel the account's open orders for the asset. This setting is useful for issuers of regulated assets who need to authorize transactions on a case-by-case basis to ensure each conforms to certain requirements.

All changes to asset authorization are performed with the allow_trust operation.

### Authorization Immutable​

With this setting, neither of the other authorization flags can be set, and the issuing account can’t be merged. You set this flag to signal to potential token holders that your issuing account and its assets will persist on ledger in an open and accessible state.

### Clawback Enabled​

With the AUTHORIZATION_CLAWBACK_ENABLED flag set, any subsequent trustlines established with this account will have clawbacks enabled. You can read more about clawbacks (and selectively controlling them on a per-trustline basis) here.

Note that this flag requires that revocable is also set.

## Example flow​

To get a sense of how authorization flags work, let's look at how an issuer of a regulated asset might use the AUTHORIZED_TO_MAINTAIN_LIABILITIES flag.

If the issuer wants to approve transactions on a case-by-base basis while allowing accounts to maintain offers, they can leave an account in the AUTHORIZED_TO_MAINTAIN_LIABILITIES state. That account can own offers, but cannot otherwise do anything with the asset.

To intitiate a new operation, the holding account requests that the issuer approve and sign a transaction. Once the issuer inspects the operation and decides to approve it, they sandwich it between a set of operations, first granting authorization, then reducing it.

Here's a payment from A to B sandwiched between set_trust_line_flags operations:

• Operation 1: Issuer uses SetTrustLineFlags to fully authorize account A, asset X
• Operation 2: Issuer uses SetTrustLineFlags to fully authorize account B, asset X
• Operation 3: Payment from A to B
• Operation 4: Issuer uses SetTrustLineFlags to set account B, asset X to AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG state
• Operation 5: Issuer uses SetTrustLineFlags to set account A, asset X to AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG state

The authorization sandwich allows the issuer to inspect the specifc payment, and to grant authorization for it and it alone. Since operations bundled in a transaction are simultaneous, A and B are only authorized for the specific, pre-approved payment operation. Complete authorization does not extend beyond the specific transaction.

## Sample code​

info

In the following code samples, proper error checking is omitted for brevity. However, you should always validate your results, as there are many ways that requests can fail. You should refer to the guide on Error Handling for tips on error management strategies.

The following example sets authorization to be both required and revocable:

var StellarSdk = require("stellar-sdk");var server = new StellarSdk.Server("https://horizon-testnet.stellar.org");// Keys for issuing accountvar issuingKeys = StellarSdk.Keypair.fromSecret(  "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4",);server  .loadAccount(issuingKeys.publicKey())  .then(function (issuer) {    var transaction = new StellarSdk.TransactionBuilder(issuer, {      fee: 100,      networkPassphrase: StellarSdk.Networks.TESTNET,    })      .addOperation(        StellarSdk.Operation.setOptions({          setFlags: StellarSdk.AuthRevocableFlag | StellarSdk.AuthRequiredFlag,        }),      )      // setTimeout is required for a transaction      .setTimeout(100)      .build();    transaction.sign(issuingKeys);    return server.submitTransaction(transaction);  })  .then(console.log)  .catch(function (error) {    console.error("Error!", error);  });