Amazon Bedrock AI Integration with Android App Without Backend | Kotlin & AWS Cognito Tutorial
September 28, 2026
Generative AI is becoming an important part of modern mobile applications. Android developers can integrate AI capabilities such as text generation, summarization, question answering, content generation and chat directly into mobile applications using Amazon Bedrock.
A common architecture is:
Android App → Your Backend API → Amazon Bedrock
But what if you don’t have your own backend server?
It is possible to build:
Android App → Amazon Cognito → Amazon Bedrock
In this architecture, the mobile application communicates directly with Amazon Bedrock using temporary AWS credentials rather than storing permanent AWS access keys inside the application.
Amazon recommends temporary credentials for applications, and its documentation specifically recommends Amazon Cognito for mobile applications.
This article explains the complete architecture and implementation approach.
What is Amazon Bedrock?
Amazon Bedrock is AWS’s managed generative AI service that provides access to foundation models from multiple providers through AWS APIs.
Instead of hosting an AI model yourself, your application sends a prompt to Amazon Bedrock and receives the generated response.
For example:
User enters:
"Summarize this paragraph"
↓
Android Application
↓
Amazon Bedrock Runtime
↓
Foundation Model
↓
AI-generated response
↓
Android UI
Amazon Bedrock currently supports multiple model providers and provides APIs such as Converse, Invoke, ConverseStream and InvokeModelWithResponseStream, depending on model compatibility. AWS recommends the bedrock-runtime endpoint for new applications.

Can Android Call Amazon Bedrock Directly?
Yes.
For an Android application, you don’t necessarily need to build your own REST API server.
A suitable architecture is:
┌──────────────────────┐
│ Android App │
│ │
│ Kotlin / Compose │
└──────────┬───────────┘
│
│
Authentication
│
▼
┌──────────────────────┐
│ Amazon Cognito │
│ Identity Pool │
└──────────┬───────────┘
│
Temporary AWS
credentials
│
▼
┌──────────────────────┐
│ Amazon Bedrock │
│ Runtime │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Foundation Model │
│ │
│ Amazon / Anthropic / │
│ Meta / Google / etc. │
└──────────────────────┘
The important part is Amazon Cognito.
You should NOT put an AWS access key and secret access key directly inside an Android application.
Instead, Cognito can provide temporary, limited-privilege AWS credentials to the mobile application. AWS explicitly recommends Cognito for mobile applications.
Why Can’t I Put AWS Access Keys in the Android App?
You should never do this:
val accessKey = "AKIAxxxxxxxx"
val secretKey = "xxxxxxxxxxxxxxxx"
Even if you put these values inside:
local.properties- BuildConfig
- encrypted strings
- native C++ code
- ProGuard/R8-obfuscated code
the credentials are ultimately distributed to the user’s device.
A determined attacker can extract application secrets.
The recommended approach is:
Android
↓
Cognito Identity Pool
↓
Temporary credentials
↓
Bedrock
Amazon Bedrock supports IAM permissions and temporary credentials.
Architecture Without Your Own Backend
The complete architecture looks like this:
AWS ACCOUNT
┌───────────────────────────────────────────────┐
│ │
│ ┌─────────────────┐ │
│ │ Cognito │ │
│ │ Identity Pool │ │
│ └────────┬────────┘ │
│ │ │
│ │ Temporary credentials │
│ ▼ │
│ ┌─────────────────┐ │
│ │ IAM Role │ │
│ │ Bedrock access │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Bedrock Runtime │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Foundation │ │
│ │ Model │ │
│ └─────────────────┘ │
│ │
└───────────────────────────────────────────────┘
▲
│
│ Internet
│
┌─────────┴──────────┐
│ │
┌────┴─────┐ ┌─────┴─────┐
│ Android │ │ iOS │
│ App │ │ App │
└──────────┘ └───────────┘
There is no custom API server in this architecture.
Step 1: Create an AWS Account
First, create or use an AWS account.
From the AWS Console, you will primarily work with:
- Amazon Bedrock
- Amazon Cognito
- IAM
- CloudWatch
You do not need EC2, Lambda, API Gateway or your own web server for this basic architecture.
Step 2: Select an Amazon Bedrock Model
Open:
AWS Console → Amazon Bedrock → Foundation Models
Choose a model that supports the Bedrock API you intend to use.
For a conversational Android application, the Converse API is particularly convenient because it provides a consistent interface across supported message-based models.
For example, you might use an Amazon Nova model.
AWS’s current SDK for Kotlin provides Bedrock Runtime examples using Amazon Nova and the Converse API.
The important point is that model availability and API compatibility vary by model and AWS Region, so check the current model documentation before selecting the model.
Step 3: Check Model Access
Depending on the model and current AWS requirements, you may need to enable or request access to the model.
In the AWS Console:
Amazon Bedrock
↓
Model access / model catalog
↓
Select required model
↓
Enable/request access if required
Do this before troubleshooting Android code.
A common mistake is to write the mobile integration first and then discover that the selected model isn’t available in the selected Region.
Step 4: Create a Cognito Identity Pool
Now create an Amazon Cognito Identity Pool.
The identity pool is responsible for providing temporary AWS credentials to the Android application.
Conceptually:
Android App
│
│ Request AWS credentials
▼
Cognito Identity Pool
│
│
▼
Temporary credentials
│
▼
IAM Role
AWS documents Cognito identity pools as a way to provide temporary, limited-privilege credentials to applications.
For a prototype, you can configure an identity pool with unauthenticated identities.
For a production application, authenticated identities are generally preferable.
Step 5: Configure Authentication
There are two broad approaches.
Option A — Unauthenticated users
The application receives temporary credentials without requiring the user to sign in.
Architecture:
Android
↓
Cognito Identity Pool
↓
Temporary credentials
↓
Bedrock
This is convenient for a proof of concept.
However, you should be careful with permissions because anyone who can run your application may potentially obtain credentials associated with the unauthenticated role.
Option B — Authenticated users
A better production architecture is:
Android
↓
User Login
↓
Cognito User Pool / external IdP
↓
Cognito Identity Pool
↓
Temporary AWS credentials
↓
Bedrock
Cognito supports user authentication and federation with identity providers.
For example:
Google Login
↓
Cognito
↓
Identity Pool
↓
Temporary AWS credentials
↓
Bedrock
Step 6: Create a Restricted IAM Role
This is one of the most important steps.
Do NOT give the mobile application’s IAM role unrestricted AWS permissions.
For example, the role should only have the Bedrock actions your application requires.
A conceptual policy might look like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "*"
}
]
}
The exact permissions should be narrowed further for your actual model/resource configuration where supported.
For applications using the Converse API, make sure the permissions and resources align with the Bedrock resources and inference configuration you’re using.
AWS provides IAM guidance for Amazon Bedrock and recommends temporary credentials rather than long-lived credentials.
Step 7: Configure the Android Project
The AWS SDK for Kotlin can target Android API level 24 or higher, making it suitable for modern Android applications.
Add the AWS SDK for Kotlin modules needed for your implementation.
For Bedrock Runtime, the relevant module is:
aws.sdk.kotlin.services.bedrockruntime
The current AWS SDK for Kotlin Bedrock Runtime module exposes operations including:
Converse
ConverseStream
InvokeModel
InvokeModelWithResponseStream
among others.
Keep AWS SDK dependencies updated rather than copying an old version from an outdated tutorial.
Step 8: Obtain Temporary Credentials
Your Android application should obtain temporary credentials through Cognito.
Conceptually:
class AwsCredentialManager {
suspend fun getCredentials() {
// Obtain temporary credentials
// from Cognito Identity Pool
}
}
The credentials should contain temporary authentication information such as:
Access Key
Secret Key
Session Token
Expiration
The important difference is:
Permanent credentials
❌
↓
Stored inside APK
Temporary credentials
✅
↓
Obtained at runtime
↓
Expire automatically
AWS recommends temporary credentials for this type of application architecture.
Step 9: Create the Bedrock Runtime Client
Once the application has temporary credentials, create a Bedrock Runtime client.
Conceptually:
val bedrockClient = BedrockRuntimeClient {
region = "us-east-1"
// Configure your temporary
// Cognito-backed credentials provider
}
The AWS SDK for Kotlin provides a dedicated BedrockRuntimeClient for model inference.
The exact credential-provider implementation depends on how you configure Cognito in your Android project.
Step 10: Send a Prompt Using Converse
For a chat application, the Converse API is a good starting point.
The basic flow is:
User enters prompt
↓
ViewModel
↓
AI Repository
↓
BedrockRuntimeClient
↓
Converse()
↓
Foundation Model
↓
Response
↓
ViewModel
↓
Compose UI
A simplified Kotlin example looks like:
suspend fun askBedrock(
prompt: String
): String {
val message = Message {
role = ConversationRole.User
content = listOf(
ContentBlock.Text(prompt)
)
}
val response = bedrockClient.converse {
modelId = "your-model-id"
messages = listOf(message)
}
return response.output
?.asMessage()
?.content
?.firstOrNull()
?.asText()
?: ""
}
The exact generated SDK types can change with SDK versions, so treat this as an architectural example and use the current SDK API reference for your installed version.
AWS provides an official Kotlin example of using Bedrock’s Converse API.
Step 11: Implement Streaming Responses
For a chat application, waiting for the entire response isn’t always the best user experience.
Instead:
User
↓
"Explain Kotlin Coroutines"
↓
Bedrock
↓
"Coroutines..."
↓
"are..."
↓
"a..."
↓
"lightweight..."
The UI can progressively display the response.
Amazon Bedrock supports streaming APIs including ConverseStream and InvokeModelWithResponseStream.
Your architecture becomes:
Android
↓
ConverseStream
↓
Bedrock
↓
Streaming tokens/chunks
↓
Flow<String>
↓
Compose UI
This works very well with Kotlin coroutines and Flow.
Step 12: Android Architecture
For a production Android application, I would structure the application like this:
com.example.aiapp
├── data
│ ├── aws
│ │ ├── CognitoCredentialProvider
│ │ └── BedrockDataSource
│ │
│ └── repository
│ └── AIRepositoryImpl
│
├── domain
│ ├── model
│ │ └── AIResponse
│ │
│ └── repository
│ └── AIRepository
│
├── presentation
│ ├── chat
│ │ ├── ChatViewModel
│ │ └── ChatScreen
│ │
│ └── components
│
└── di
└── AwsModule
The dependency flow should be:
Compose UI
↓
ViewModel
↓
Use Case
↓
Repository
↓
BedrockDataSource
↓
AWS SDK
↓
Amazon Bedrock
This keeps AWS-specific implementation details out of your UI.
Step 13: Example ViewModel
A simplified ViewModel could look like:
class ChatViewModel(
private val repository: AIRepository
) : ViewModel() {
private val _response = MutableStateFlow("")
val response = _response.asStateFlow()
fun askQuestion(prompt: String) {
viewModelScope.launch {
try {
repository.ask(prompt)
.collect { chunk ->
_response.value += chunk
}
} catch (e: Exception) {
// Handle error
}
}
}
}
This is particularly useful when using ConverseStream.
Step 14: Handle AWS Errors
Your application should handle at least:
Authentication failure
Authorization failure
AccessDeniedException
Throttling
Model unavailable
Invalid model ID
Invalid request
Network failure
Timeout
Expired credentials
Region mismatch
For example:
try {
val result = repository.ask(prompt)
} catch (e: Exception) {
when {
e.message?.contains("AccessDenied") == true -> {
// IAM / permission problem
}
e.message?.contains("Throttl") == true -> {
// Retry/backoff
}
else -> {
// Generic error
}
}
}
Do not expose raw AWS exception messages directly to users.
Step 15: Region Is Important
Suppose your application uses:
us-east-1
Your Bedrock model must be available in that Region or accessible through an appropriate inference configuration.
Architecture:
Android
↓
Cognito
↓
us-east-1
↓
Bedrock Runtime
↓
Model
If the model isn’t available in the selected Region, you can encounter errors even though your IAM configuration is correct.
AWS maintains model availability and compatibility information by Region and API.
Step 16: Add Guardrails
For a production AI application, consider Amazon Bedrock Guardrails.
For example:
User prompt
↓
Bedrock
↓
Guardrail
↓
Foundation Model
↓
Response
Guardrails can help control harmful or unwanted content and provide additional governance.
The Bedrock Runtime API includes ApplyGuardrail, and model/API compatibility should be checked for your specific architecture.
Step 17: Do You Need API Gateway?
For your specific requirement:
No.
You don’t necessarily need:
Android
↓
API Gateway
↓
Lambda
↓
Bedrock
You can use:
Android
↓
Cognito
↓
Bedrock
This eliminates:
- Your own REST API
- API Gateway configuration
- Lambda function
- Backend deployment
- Backend server maintenance
However, there is an important security and product-design tradeoff.
Direct Bedrock vs Backend Architecture
Architecture 1 — Direct Mobile Integration
Android
↓
Cognito
↓
Bedrock
Advantages
- No custom backend
- Simple architecture
- Lower infrastructure complexity
- Fast prototype development
- Good for learning
- Excellent for proof-of-concept applications
Disadvantages
- AWS permissions are exposed to the client through temporary credentials
- Fine-grained server-side business logic is harder
- Usage controls require careful IAM/Cognito design
- Abuse protection becomes more important
- Prompt/business rules are visible in the client
- You have less centralized control
Architecture 2 — Backend-Based Integration
Android
↓
Your API
↓
Lambda / Server
↓
Bedrock
Advantages
- Centralized authorization
- Easier usage controls
- Better business-rule enforcement
- Easier server-side prompt management
- Easier integration with databases
- Easier centralized logging and analytics
Disadvantages
- More infrastructure
- More development work
- Additional operational cost
- Backend maintenance
Which Architecture Should You Use?
For your stated requirement:
“I don’t have my own API server and I want AWS → Mobile direct integration.”
Start with:
Android
↓
Amazon Cognito Identity Pool
↓
Temporary AWS credentials
↓
Amazon Bedrock Runtime
↓
Converse / ConverseStream
↓
Foundation Model
This is a legitimate architecture for a mobile application, provided that IAM permissions, authentication and abuse controls are designed carefully.
For a production application with sensitive business logic or high-value AI functionality, consider introducing a backend later.
Important Security Consideration
A very important point:
No backend does not mean no security.
Your Android application is distributed to potentially untrusted devices.
Therefore:
DO NOT
Android
↓
Permanent AWS Access Key
↓
Bedrock
Instead:
Android
↓
Cognito
↓
Temporary credentials
↓
Restricted IAM Role
↓
Bedrock
AWS specifically recommends temporary credentials and identifies Cognito as the recommended approach for mobile applications.
Complete End-to-End Flow
Here is the complete flow for an Android AI application:
USER
│
▼
┌───────────────┐
│ Android App │
│ Jetpack │
│ Compose │
└───────┬───────┘
│
│ Login / Identity
▼
┌───────────────┐
│ Cognito │
│ Identity Pool │
└───────┬───────┘
│
│ Temporary credentials
▼
┌───────────────┐
│ IAM Role │
│ Restricted │
│ Permissions │
└───────┬───────┘
│
│ Signed AWS request
▼
┌───────────────┐
│ Bedrock │
│ Runtime │
└───────┬───────┘
│
│ Converse
│ / ConverseStream
▼
┌───────────────┐
│ Foundation │
│ Model │
└───────┬───────┘
│
│ AI response
▼
┌───────────────┐
│ Android UI │
│ Chat / Result │
└───────────────┘
Example Use Cases
This architecture can be used to build:
AI Chat App
User → Question → Bedrock → Answer
AI Summarization App
Document
↓
Android
↓
Bedrock
↓
Summary
AI Writing Assistant
User text
↓
"Rewrite professionally"
↓
Bedrock
↓
Improved text
AI Learning App
Question
↓
Bedrock
↓
Explanation
↓
Quiz generation
AI Mobile Developer Assistant
For example:
User:
"Explain this Kotlin code"
↓
Amazon Bedrock
↓
AI explanation
Recommended Technology Stack
For an Android implementation, a modern stack could be:
Android
│
├── Kotlin
├── Jetpack Compose
├── ViewModel
├── Coroutines
├── StateFlow
│
├── AWS SDK for Kotlin
│
├── Amazon Cognito
│ └── Identity Pool
│
└── Amazon Bedrock
└── Bedrock Runtime
├── Converse
└── ConverseStream
The AWS SDK for Kotlin officially supports Android API level 24+ and provides Bedrock Runtime examples.
Recommended Development Strategy
If you are learning Amazon Bedrock integration, don’t start with a complex production application.
Build it in stages.
Phase 1 — AWS Console
Create AWS account
↓
Choose Region
↓
Enable model access
↓
Test model in Bedrock console
Phase 2 — Cognito
Create Identity Pool
↓
Configure authentication
↓
Create IAM role
↓
Add minimal Bedrock permissions
Phase 3 — Android
Create Android project
↓
Add AWS SDK for Kotlin
↓
Configure Cognito
↓
Obtain temporary credentials
↓
Create BedrockRuntimeClient
Phase 4 — AI
Text input
↓
Converse()
↓
AI response
↓
Display in Compose
Phase 5 — Production
Add:
Authentication
Rate limiting strategy
IAM restrictions
Guardrails
Error handling
Logging
Monitoring
Retry strategy
Cost controls
Cost Considerations
Amazon Bedrock is generally usage-based rather than requiring you to operate a model server yourself.
Your costs depend on factors such as:
- Model
- Input tokens
- Output tokens
- Requests
- Region
- Streaming/other API usage
- Additional Bedrock features
Therefore, don’t assume that a direct mobile architecture is automatically free.
Before releasing the application publicly, configure appropriate AWS billing alerts and monitor Bedrock usage.
Final Architecture Recommendation
For your exact requirement, I recommend starting with this:
ANDROID APP
│
▼
Amazon Cognito
Identity Pool
│
▼
Temporary Credentials
│
▼
IAM Role
│
Limited Bedrock
permissions
│
▼
Bedrock Runtime
│
┌────────┴────────┐
│ │
Converse ConverseStream
│ │
└────────┬────────┘
▼
AI Model
│
▼
AI Response
│
▼
Android UI
The key takeaway is:
You do not need to build your own API server just to connect an Android application to Amazon Bedrock.
A direct mobile architecture can use Amazon Cognito + temporary AWS credentials + IAM + Amazon Bedrock Runtime, with the Android application calling Bedrock directly. AWS provides an SDK for Kotlin that supports Android and includes Bedrock Runtime examples.
For new Bedrock applications, AWS currently recommends the bedrock-runtime endpoint, with Converse being a useful model-agnostic API for supported message-based models.
All the below queries are answered in this post.
How to integrate Amazon Bedrock with Android app
How to use Amazon Bedrock without backend
Amazon Bedrock direct integration with Android
Amazon Bedrock Kotlin Android tutorial
How to call Amazon Bedrock from mobile app
Amazon Cognito and Bedrock Android integration
AWS generative AI integration in Android
Build AI Android app using Amazon Bedrock