> For the complete documentation index, see [llms.txt](https://docs.keyless.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keyless.io/consumer/mobile-sdk-reference/pin-authentication.md).

# PIN authentication

For authentication scenarios that don't necessitate biometric recognition, you can use PIN as an alternative.

{% hint style="warning" %}
PIN authentication has limited capabilities compared to biometric authentication. PIN supports:

* [operation info](/consumer/mobile-sdk-guide/authentication.md#operation-info),
* [jwt signing](/consumer/mobile-sdk-reference/jwt-signing.md),
  {% endhint %}

Keyless requires at least one of the following authentication factor to be present for each user:

* biometric factor
* PIN factor

PIN factor can be any valid `String`. Numbers are not enforced but are recommended, given the familiarity of numeric PINs for end users.

## Enrollment with PIN

To enroll using the PIN factor create the following configuration:

{% tabs %}
{% tab title="Android" %}

```kotlin
val configuration = PinEnrollConfig(pin = "1234")

Keyless.enroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinEnrollConfig(pin: "1234")

Keyless.enroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration = EnrollmentConfiguration.builder
  .withPin("1234")
  .build()

Keyless.enroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration = Keyless.EnrollmentConfiguration.builder
  .withPin("1234")
  .build()

Keyless.enroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = PinEnrollConfig(
    pin: "myPin"
);

try {
    await Keyless.instance.enroll(configuration);
    print("Enrollment successful");
} catch (error) {
    print("Enrollment failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinEnrollConfig({
  pin: '1234',
});

const result = await Keyless.enroll(config);
result.fold({
  onSuccess(data) {
    logConsole('Auth result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}

To enroll multiple authentication factors you need call `Keyless.enroll` for each factor.

## Authentication with PIN

To authenticate using the PIN factor create the following configuration:

{% tabs %}
{% tab title="Android" %}

```kotlin
val configuration = PinAuthConfig(pin = "1234")

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinAuthConfig(pin: "1234")

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration = AuthenticationConfiguration.builder
  .withPin("1234")
  .build()

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration = Keyless.AuthenticationConfiguration.builder
  .withPin("1234")
  .build()

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = PinAuthConfig(
    pin: "1234"
);

try {
    final result = await Keyless.instance.authenticate(configuration);
    print("Authentication successful");
} catch (error) {
    print("Authentication failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinAuthConfig({
  pin: '1234',
});

const result = await Keyless.authenticate(config);
result.fold({
  onSuccess(data) {
    logConsole('Auth result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}

## De-enrollment with PIN

{% hint style="warning" %}
Note that de-enrolling deletes the user biometric factor as well as the PIN factor. If you just want to remove the PIN authentication factor, use the [PIN utilities](#pin-utilities) instead.
{% endhint %}

To de-enroll using the PIN authentication factor, create the following configuration:

{% tabs %}
{% tab title="Android" %}

```kotlin
val configuration = PinDeEnrollConfig(pin = "1234")

Keyless.deEnroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinDeEnrollConfig(pin: "1234")

Keyless.deEnroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration =
DeEnrollmentConfiguration.builder
  .withPin("myPin")
  .build()

Keyless.deEnroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration =
Keyless.DeEnrollmentConfiguration.builder
  .withPin("myPin")
  .build()

Keyless.deEnroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = PinDeEnrollConfig(
    pin: "1234"
);

try {
    await Keyless.instance.deEnroll(configuration);
    print("De-enrollment successful");
} catch (error) {
    print("De-enrollment failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinDeEnrollConfig('1234');

const result = await Keyless.deEnroll(config);
result.fold({
  onSuccess(data) {
    logConsole('DeEnroll result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('DeEnroll result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}

## Remove PIN (keeping biometric factor)

To remove the PIN factor, while still keeping the biometric factor, perform a biometric authentication using the following configuration:

{% tabs %}
{% tab title="Android" %}

```kotlin
val configuration = BiomAuthConfig(shouldRemovePin = true)

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  BiomAuthConfig(shouldRemovePin: true)

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration =
AuthenticationConfiguration.builder
  .removingPin()
  .build()

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration =
Keyless.AuthenticationConfiguration.builder
  .removingPin()
  .build()

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = BiomAuthConfig(
    shouldRemovePin: true
);

try {
    await Keyless.instance.authenticate(configuration);
    print("Pin remove successful");
} catch (error) {
    print("Pin remove failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript

const config = new BiomAuthConfig({
  shouldRemovePin: true,
});

const result = await Keyless.deEnroll(config);
result.fold({
  onSuccess(data) {
    logConsole('Auth result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}

## PIN utilities

To change the PIN use the `newPin` parameter in the `PinAuthConfig`:

{% tabs %}
{% tab title="Android" %}

```kotlin
val configuration = PinAuthConfig(pin = "1234", newPin = "5678")

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinAuthConfig(pin: "1234", newPin: "5678")

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Future<void> changePin({
  required String oldPin,
  required String newPin
}) async
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinAuthConfig({
  pin: '1234',
  newPin: '5678',
});

const result = await Keyless.authenticate(config);
result.fold({
  onSuccess(data) {
    logConsole('Auth result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}

To remove the PIN factor and keep the user enrolled with the biometric factor use the `shouldRemovePin` parameter in `PinAuthConfig`:

{% tabs %}
{% tab title="Android" %}

```kotlin
val configuration = PinAuthConfig(pin = "1234", shouldRemovePin = true)

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinAuthConfig(pin: "1234", shouldRemovePin: true)

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Future<void> removePin({
  required String pin
}) async
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinAuthConfig({
  pin: '1234',
  shouldRemovePin: true,
});

const result = await Keyless.authenticate(config);
result.fold({
  onSuccess(data) {
    logConsole('Auth result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}
