Blacklist User Attributes

If there are user fields that should not be stored in Auth0 databases due to privacy reasons, you can blacklist them.

Use the Management API

To blacklist attributes make a PATCH call to the Update Connection endpoint of the Management API.

Step 1. Get a token

First, you need a valid access token in order to access that endpoint. The token must include the update:connections scope.

You can either get one manually from the Dashboard, or automate the process (i.e. build a simple command line tool that generates tokens). For detailed steps on how to do either, refer to The Auth0 Management APIv2 Token.

Step 2. Call the API

One you have the token (and the list of attributes to be blacklisted), you are ready to call the API.

Here is a sample HTTP request that blacklists two attributes: ethnicity and gender.


curl --request PATCH \
  --url 'https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID' \
  --header 'authorization: Bearer YOUR_TOKEN' \
  --data '{"options": {"non_persistent_attrs": ["ethnicity", "gender"]}", "enabled_clients": [""]}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID");
var request = new RestRequest(Method.PATCH);
request.AddHeader("authorization", "Bearer YOUR_TOKEN");
request.AddParameter("undefined", "{\"options\": {\"non_persistent_attrs\": [\"ethnicity\", \"gender\"]}\", \"enabled_clients\": [\"\"]}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID"

	payload := strings.NewReader("{\"options\": {\"non_persistent_attrs\": [\"ethnicity\", \"gender\"]}\", \"enabled_clients\": [\"\"]}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("authorization", "Bearer YOUR_TOKEN")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.patch("https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID")
  .header("authorization", "Bearer YOUR_TOKEN")
  .body("{\"options\": {\"non_persistent_attrs\": [\"ethnicity\", \"gender\"]}\", \"enabled_clients\": [\"\"]}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID",
  "method": "PATCH",
  "headers": {
    "authorization": "Bearer YOUR_TOKEN"
  },
  "data": "{\"options\": {\"non_persistent_attrs\": [\"ethnicity\", \"gender\"]}\", \"enabled_clients\": [\"\"]}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PATCH',
  url: 'https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID',
  headers: { authorization: 'Bearer YOUR_TOKEN' },
  body: '{"options": {"non_persistent_attrs": ["ethnicity", "gender"]}", "enabled_clients": [""]}' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_TOKEN" };

NSData *postData = [[NSData alloc] initWithData:[@"{"options": {"non_persistent_attrs": ["ethnicity", "gender"]}", "enabled_clients": [""]}" dataUsingEncoding:NSUTF8StringEncoding]];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PATCH",
  CURLOPT_POSTFIELDS => "{\"options\": {\"non_persistent_attrs\": [\"ethnicity\", \"gender\"]}\", \"enabled_clients\": [\"\"]}",
  CURLOPT_HTTPHEADER => array(
    "authorization: Bearer YOUR_TOKEN"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("")

payload = "{\"options\": {\"non_persistent_attrs\": [\"ethnicity\", \"gender\"]}\", \"enabled_clients\": [\"\"]}"

headers = { 'authorization': "Bearer YOUR_TOKEN" }

conn.request("PATCH", "/YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Patch.new(url)
request["authorization"] = 'Bearer YOUR_TOKEN'
request.body = "{\"options\": {\"non_persistent_attrs\": [\"ethnicity\", \"gender\"]}\", \"enabled_clients\": [\"\"]}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = ["authorization": "Bearer YOUR_TOKEN"]

let postData = NSData(data: "{"options": {"non_persistent_attrs": ["ethnicity", "gender"]}", "enabled_clients": [""]}".dataUsingEncoding(NSUTF8StringEncoding)!)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

Where:

  • YOUR_CONNECTION_ID is the Id of the connection for which these attributes will be blacklisted
  • YOUR_TOKEN is the access token you got in the previous step
  • The options.non_persistent_attrs object holds an array of the attributes that will be blacklisted

Limitations

  • Only root fields (e.g. user.name or user.email) can be blacklisted
  • When you blacklist attributes, they will be still be available via rules and outgoing tokens. However, if any of the following apply, the blacklist attributes will not be included in tokens:
    • You have enabled multifactor authentication
    • You have performed a redirect via rules
    • Your app is using delegation (and you haven't set scope = passthrough)
    • Your app is using impersonation
    • You have enabled the Use Auth0 instead of the IdP to do Single Sign On setting
  • For SAMLP connections, if you enable Debug mode, your logs will contain information on the blacklisted attributes

Working around the limitations

If any of these limitations are unacceptable, you can write a rule to encrypt the data and have the data persist to the user.app_metadata object.

Was this article helpful?