public CreateHashedApiKeyResponse create(final CreateHashedApiKeyRequest createHashedApiKeyRequest) {
        Objects.requireNonNull(createHashedApiKeyRequest);

        return securityContext.secureResult(AppPermission.MANAGE_API_KEYS, () -> {
            checkAdditionalPerms(createHashedApiKeyRequest.getOwner());
            // We want both a unique prefix and hash so keep generating new keys till we
            // get one that is unique on both
            int attempts = 0;
            do {
                attempts++;
                try {
                    return createNewApiKey(createHashedApiKeyRequest);
                } catch (DuplicateApiKeyException e) {
                    LOGGER.debug("Duplicate hash on attempt {}, going round again", attempts);
                }
            } while (attempts < MAX_CREATION_ATTEMPTS);

            throw new RuntimeException(LogUtil.message("Unable to create API key with unique prefix and hash " +
                                                       "after {} attempts", attempts));
        });
    }
Fetch the verified {@link UserIdentity} for the passed API key.
If the hash of the API key matches one in the database and that key is enabled
and not expired then the {@link UserIdentity} will be returned, else an empty {@link Optional}
is returned.
stroom-security/stroom-security-impl/src/main/java/stroom/security/impl/apikey/ApiKeyService.java