-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion on Enabling atProtocol Access for Web Apps #2034
Comments
Findings on Authentication and Key Management1. Authenticating to Secondary ServicesProposed Solution:
Rationale:
2. Performing Operations on Secondary ServicesProposed Solution:
Rationale:
Benefits:
Alternatives Considered
Conclusion:
|
WebAuthn Passkey FlowsequenceDiagram
participant User
participant Browser
participant Server
participant Authenticator
Note over Authenticator: The Authenticator actor in the WebAuthn passkey flow refers to the hardware or software device that manages the user's credentials and performs the cryptographic operations required for authentication. There are two primary types of authenticators:
User->>Browser: Register with Website
Browser->>Server: Request registration options
Server->>Browser: Send registration options (challenge, public key params, etc.)
Browser->>Authenticator: Create credential (key pair, attestation)
Authenticator-->>Browser: Return credential
Browser->>Server: Complete registration with credential
Server->>Browser: Confirm registration success
User->>Browser: Authenticate with Website
Browser->>Server: Request authentication options
Server->>Browser: Send authentication options (challenge, allow credentials, etc.)
Browser->>Authenticator: Get assertion (sign challenge)
Authenticator-->>Browser: Return assertion
Browser->>Server: Complete authentication with assertion
Server->>Browser: Confirm authentication success
Sign ChallengeWhen the
VerifyWhen the
Note: The In both cases, the private key remains securely stored within the authenticator, ensuring that sensitive operations are performed securely and without exposure of the private key. |
index.html used for the demo: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAuthn Client</title>
</head>
<body>
<h1>WebAuthn with Passkeys</h1>
<button id="register">Register</button>
<button id="authenticate">Authenticate</button>
<script>
document.getElementById('register').addEventListener('click', async () => {
try {
// Request registration options from the server
const response = await fetch('http://localhost:8080/register', { method: 'POST' });
const options = await response.json();
// Convert Base64 strings to ArrayBuffer
options.publicKey.challenge = base64ToArrayBuffer(options.publicKey.challenge);
options.publicKey.user.id = base64ToArrayBuffer(options.publicKey.user.id);
options.publicKey.excludeCredentials.forEach(cred => {
cred.id = base64ToArrayBuffer(cred.id);
});
// Set the relying party ID explicitly to 'localhost'
options.publicKey.rp.id = 'localhost';
// Create a new credential using WebAuthn
const credential = await navigator.credentials.create({ publicKey: options.publicKey });
// Send the credential to the server to complete registration
await fetch('http://localhost:8080/register/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: credential.id,
type: credential.type,
rawId: arrayBufferToBase64(credential.rawId),
response: {
clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON),
attestationObject: arrayBufferToBase64(credential.response.attestationObject)
}
})
});
alert('Registration successful');
} catch (error) {
console.error('Error during registration:', error);
alert('Registration failed');
}
});
document.getElementById('authenticate').addEventListener('click', async () => {
try {
const userId = prompt('Enter your user ID:');
// Request authentication options from the server
const response = await fetch('http://localhost:8080/authenticate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId })
});
const options = await response.json();
// Convert Base64 strings to ArrayBuffer
options.publicKey.challenge = base64ToArrayBuffer(options.publicKey.challenge);
options.publicKey.allowCredentials.forEach(cred => {
cred.id = base64ToArrayBuffer(cred.id);
});
// Set the relying party ID explicitly to 'localhost'
options.publicKey.rpId = 'localhost';
// Get an assertion using WebAuthn
const assertion = await navigator.credentials.get({ publicKey: options.publicKey });
// Send the assertion to the server to complete authentication
await fetch('http://localhost:8080/authenticate/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: assertion.id,
type: assertion.type,
rawId: arrayBufferToBase64(assertion.rawId),
response: {
clientDataJSON: arrayBufferToBase64(assertion.response.clientDataJSON),
authenticatorData: arrayBufferToBase64(assertion.response.authenticatorData),
signature: arrayBufferToBase64(assertion.response.signature),
userHandle: assertion.response.userHandle ? arrayBufferToBase64(assertion.response.userHandle) : null
}
})
});
alert('Authentication successful');
} catch (error) {
console.error('Error during authentication:', error);
alert('Authentication failed');
}
});
// Helper function to convert ArrayBuffer to Base64
function arrayBufferToBase64(buffer) {
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
}
// Helper function to convert Base64 to ArrayBuffer
function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
</script>
</body>
</html> |
@VJag quick notes re integrating with APKAM enrollment flow
|
Is your feature request related to a problem? Please describe.
The primary goal is to enable atProtocol access for web applications. To achieve this, we need to undertake the following steps:
Describe the solution you'd like
Objective:
The primary goal is to enable atProtocol access for web applications. To achieve this, we need to undertake the following steps:
WebSocket Support for atServer:
Develop WASM Wrapper for atClient Methods:
SDK Support for WebSocket Connections:
In-Memory Alternative for Dart Hive:
Discussion Points:
Objective of this Discussion:
The purpose of this discussion is to analyze and conclude whether pursuing this journey is worthwhile. We aim to gather insights and opinions from the engineering team to make an informed decision.
Describe alternatives you've considered
No response
Additional context
No response
The text was updated successfully, but these errors were encountered: