Skip to content

Commit 311b8ba

Browse files
committed
chore: implement security best practices (non-root Docker, configurable CORS, sanitized logs)
1 parent c6ec965 commit 311b8ba

File tree

4 files changed

+23
-17
lines changed

4 files changed

+23
-17
lines changed

Dockerfile

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,22 @@ RUN apt-get update \
3838
libpq5 \
3939
&& rm -rf /var/lib/apt/lists/*
4040

41+
# Create a non-root user
42+
RUN groupadd -r appuser && useradd -r -g appuser appuser
43+
4144
# Set the working directory
4245
WORKDIR /app
4346

4447
# Copy virtual environment from builder
4548
COPY --from=builder /app/.venv /app/.venv
4649

47-
# Copy application code
48-
COPY --from=builder /app/intentkit /app/intentkit
49-
COPY --from=builder /app/app /app/app
50-
COPY --from=builder /app/scripts /app/scripts
50+
# Copy application code with correct ownership
51+
COPY --from=builder --chown=appuser:appuser /app/intentkit /app/intentkit
52+
COPY --from=builder --chown=appuser:appuser /app/app /app/app
53+
COPY --from=builder --chown=appuser:appuser /app/scripts /app/scripts
54+
55+
# Switch to non-root user
56+
USER appuser
5157

5258
ARG RELEASE=local
5359
ENV RELEASE=$RELEASE

app/api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def _load_agent_api_docs() -> str:
114114
# Add CORS middleware to the Agent API sub-application
115115
_ = agent_app.add_middleware(
116116
CORSMiddleware,
117-
allow_origins=["*"], # Allows all origins
117+
allow_origins=config.cors_allow_origins, # Allows configured origins
118118
allow_methods=["*"], # Allows all methods
119119
allow_headers=["*"], # Allows all headers
120120
)
@@ -187,7 +187,7 @@ async def lifespan(app: FastAPI):
187187
# Add CORS middleware
188188
_ = app.add_middleware(
189189
CORSMiddleware,
190-
allow_origins=["*"], # Allows all origins
190+
allow_origins=config.cors_allow_origins, # Allows configured origins
191191
allow_methods=["*"], # Allows all methods
192192
allow_headers=["*"], # Allows all headers
193193
)

intentkit/config/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ def __init__(self) -> None:
114114
self.open_api_base_url: str = self.load(
115115
"OPEN_API_BASE_URL", "http://localhost:8000"
116116
)
117+
# CORS
118+
cors_origins_raw = self.load("CORS_ALLOW_ORIGINS", "*")
119+
self.cors_allow_origins: list[str] = [
120+
o.strip() for o in cors_origins_raw.split(",") if o.strip()
121+
]
117122
# CDP SDK Configuration
118123
self.cdp_api_key_id: str | None = self.load("CDP_API_KEY_ID")
119124
self.cdp_api_key_secret: str | None = self.load("CDP_API_KEY_SECRET")

intentkit/wallets/privy_client.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,9 @@ async def create_wallet(
244244

245245
if response.status_code not in (200, 201):
246246
logger.info(
247-
"Privy create_wallet response: status=%s auth_sig_count=%s body=%s",
247+
"Privy create_wallet response: status=%s auth_sig_count=%s",
248248
response.status_code,
249249
signature_count,
250-
response.text,
251250
)
252251

253252
raise IntentKitAPIError(
@@ -351,12 +350,11 @@ async def sign_message(self, wallet_id: str, message: str) -> str:
351350

352351
if response.status_code not in (200, 201):
353352
logger.info(
354-
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s body=%s",
353+
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s",
355354
wallet_id,
356355
payload.get("method"),
357356
response.status_code,
358357
signature_count,
359-
response.text,
360358
)
361359

362360
raise IntentKitAPIError(
@@ -428,12 +426,11 @@ async def sign_hash(self, wallet_id: str, hash_bytes: bytes) -> str:
428426

429427
if response.status_code not in (200, 201):
430428
logger.info(
431-
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s body=%s",
429+
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s",
432430
wallet_id,
433431
payload.get("method"),
434432
response.status_code,
435433
signature_count,
436-
response.text,
437434
)
438435

439436
raise IntentKitAPIError(
@@ -497,12 +494,11 @@ async def sign_typed_data(self, wallet_id: str, typed_data: dict[str, Any]) -> s
497494

498495
if response.status_code not in (200, 201):
499496
logger.info(
500-
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s body=%s",
497+
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s",
501498
wallet_id,
502499
payload.get("method"),
503500
response.status_code,
504501
signature_count,
505-
response.text,
506502
)
507503

508504
raise IntentKitAPIError(
@@ -580,18 +576,17 @@ async def send_transaction(
580576

581577
if response.status_code not in (200, 201):
582578
logger.info(
583-
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s body=%s",
579+
"Privy rpc response: wallet_id=%s method=%s status=%s auth_sig_count=%s",
584580
wallet_id,
585581
payload.get("method"),
586582
response.status_code,
587583
signature_count,
588-
response.text,
589584
)
590585

591586
raise IntentKitAPIError(
592587
response.status_code,
593588
"PrivyAPIError",
594-
f"Failed to send transaction: {response.text}",
589+
"Failed to send transaction with Privy wallet",
595590
)
596591

597592
data_response = response.json()

0 commit comments

Comments
 (0)