Skip to content

Commit 37f7d08

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

File tree

7 files changed

+27
-31
lines changed

7 files changed

+27
-31
lines changed

Dockerfile

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,30 @@ 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
5460
ENV PATH="/app/.venv/bin:$PATH"
5561

62+
# Create a non-root user for better security
63+
RUN useradd -ms /bin/bash appuser && chown -R appuser:appuser /app
64+
USER appuser
65+
5666
# Command to run the application
5767
CMD ["uvicorn", "app.api:app", "--host", "0.0.0.0", "--port", "80"]

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
)

docs/go.mod

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
module github.com/crestalnetwork/intentkit/docs
22

33
go 1.22
4-
5-
require (
6-
github.com/imfing/hextra v0.11.1 // indirect
7-
)

docs/go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +0,0 @@
1-
github.com/imfing/hextra v0.11.1 h1:8pTc4ReYbzGTHAnyiebmlT3ijFfIXiGu1r7tM/UGjFI=
2-
github.com/imfing/hextra v0.11.1/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=

integrations/telegram/go.sum

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
2-
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
31
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
42
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
53
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
@@ -16,8 +14,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
1614
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1715
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1816
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
19-
github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4=
20-
github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
2117
github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk=
2218
github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
2319
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
@@ -32,7 +28,6 @@ github.com/grbit/go-json v0.11.0 h1:bAbyMdYrYl/OjYsSqLH99N2DyQ291mHy726Mx+sYrnc=
3228
github.com/grbit/go-json v0.11.0/go.mod h1:IYpHsdybQ386+6g3VE6AXQ3uTGa5mquBme5/ZWmtzek=
3329
github.com/hack-fan/config v0.0.0-20200528030741-0a9be90586b6 h1:AoJN0N5BcQtK9JBPEFC+Qb06R6Hd6ML3VIVkYCdzknM=
3430
github.com/hack-fan/config v0.0.0-20200528030741-0a9be90586b6/go.mod h1:pNBw7sPcXydnQFm0YXMynTZdFqKXtFetAL2cy6DulLM=
35-
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 h1:VHgatEHNcBFEB7inlalqfNqw65aNkM1lGX2yt3NmbS8=
3631
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
3732
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
3833
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
@@ -89,8 +84,6 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
8984
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
9085
github.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZyVI=
9186
github.com/valyala/fasthttp v1.69.0/go.mod h1:4wA4PfAraPlAsJ5jMSqCE2ug5tqUPwKXxVj8oNECGcw=
92-
github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM=
93-
github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
9487
github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4=
9588
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
9689
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
@@ -115,7 +108,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
115108
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
116109
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
117110
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
118-
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
119111
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
120112
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
121113
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

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)