⚠️Blast API (blastapi.io) ends Oct 31. Migrate to Dwellir and skip Alchemy's expensive compute units.
Switch Today →
Skip to main content

Coming soon: Need support for this? Email support@dwellir.com if you want early access

Streaming Authentication

Streaming API authentication provides secure access control for gRPC transaction streams, ensuring only authorized clients can subscribe to blockchain data feeds. Proper authentication is essential for production deployments, rate limiting, access control, and preventing unauthorized resource consumption.

Overview#

The Aptos streaming service uses bearer token authentication negotiated during channel setup. This approach provides security without sacrificing performance, allowing long-lived streaming connections while maintaining proper access controls. Authentication tokens are validated once during connection establishment and remain valid for the duration of the stream.

Authentication Methods#

Bearer Token Authentication#

import { credentials, Metadata } from "@grpc/grpc-js";

// Create metadata with API key
const metadata = new Metadata();
metadata.add("authorization", `Bearer ${process.env.API_KEY}`);

// Establish authenticated connection
const client = new TransactionStreamClient(
"stream.aptos.dwellir.com:443",
credentials.createSsl(),
{
channelOverride: channel
}
);

// Use metadata in stream requests
const stream = client.subscribe(request, metadata);

Mutual TLS (mTLS)#

For enterprise deployments, mTLS provides certificate-based authentication:

import * as fs from "fs";

const rootCert = fs.readFileSync("ca-cert.pem");
const clientKey = fs.readFileSync("client-key.pem");
const clientCert = fs.readFileSync("client-cert.pem");

const sslCredentials = credentials.createSsl(
rootCert,
clientKey,
clientCert
);

const client = new TransactionStreamClient(
"stream.aptos.dwellir.com:443",
sslCredentials
);

Real-World Use Cases#

  1. Production Services: Secure streaming connections for production applications handling sensitive transaction data or serving multiple users.

  2. Multi-Tenant Systems: Isolate stream access per customer using separate API keys with individual rate limits and quotas.

  3. Analytics Platforms: Authenticate data ingestion pipelines that process blockchain streams for business intelligence and reporting.

  4. Trading Systems: Secure real-time market data feeds for trading bots and algorithmic trading systems with guaranteed access.

  5. Compliance Monitoring: Authenticate regulatory compliance systems that monitor transactions for suspicious activities or reporting requirements.

  6. Enterprise Infrastructure: Integrate blockchain streams into corporate systems with certificate-based authentication and access controls.

Best Practices#

Rotate Keys Regularly: Implement automated key rotation schedules to minimize exposure if credentials are compromised.

Use Environment Variables: Never hard-code API keys or certificates - store them securely in environment variables or secrets management systems.

Implement Retry Logic: Handle authentication failures gracefully with exponential backoff and automatic retry mechanisms.

Monitor Authentication Status: Track authentication failures and unusual patterns that might indicate security issues.

Separate Keys Per Environment: Use different API keys for development, staging, and production to prevent accidental production access.

Implement Timeout Handling: Set appropriate timeout values for authentication handshakes to fail fast on connection issues.

Log Security Events: Maintain audit logs of authentication attempts, failures, and key usage for security monitoring.

Connection Management#

class AuthenticatedStreamClient {
private client: TransactionStreamClient;
private metadata: Metadata;

constructor(apiKey: string) {
this.metadata = new Metadata();
this.metadata.add("authorization", `Bearer ${apiKey}`);

this.client = new TransactionStreamClient(
"stream.aptos.dwellir.com:443",
credentials.createSsl()
);
}

subscribe(request: SubscribeRequest): ClientReadableStream {
return this.client.subscribe(request, this.metadata);
}

// Handle authentication errors
private handleAuthError(error: Error) {
if (error.message.includes("Unauthenticated")) {
console.error("Authentication failed - check API key");
// Trigger key refresh or alert
}
}
}

Security Considerations#

TLS Encryption: Always use TLS/SSL encryption for streaming connections to protect credentials and data in transit.

Key Storage: Store API keys and certificates in secure vaults (HashiCorp Vault, AWS Secrets Manager, etc.) rather than configuration files.

Access Scope: Request minimum necessary permissions for API keys - don't use admin keys for read-only streaming.

Expiration Policies: Implement key expiration policies and automated renewal processes to maintain security hygiene.

Rate Limiting: Understand rate limits associated with your API keys and implement client-side throttling.

Error Handling: Don't expose authentication details in error messages or logs that might leak credentials.

Troubleshooting#

Authentication Failures#

stream.on("error", (error) => {
if (error.code === grpc.status.UNAUTHENTICATED) {
console.error("Authentication failed");
// Check API key validity
// Verify key has required permissions
// Confirm key hasn't expired
}
});

Connection Issues#

const connectionDeadline = new Date(Date.now() + 5000);

const stream = client.subscribe(request, metadata, {
deadline: connectionDeadline
});

stream.on("status", (status) => {
if (status.code !== grpc.status.OK) {
console.error(`Connection failed: ${status.details}`);
}
});