ããŒãã³ãŒããããå€ã¯ãäžèŠãããšæã£åãæ©ãæ¹æ³ã®ããã«èŠããŸããéçºè ãããŒã¿ããŒã¹ã®URLãå¿ èŠãšããå Žåããããæ¥ç¶æååã«çŽæ¥å ¥åããŠå ã«é²ã¿ãŸãã3ãæåŸãURLã倿Žããã1ã€ã®ãã¡ã€ã«ã§ã¯å€æŽãåæ ããããã®ã®ãä»ã®4ã€ã®ãã¡ã€ã«ã§ã¯å€æŽãèŠèœãšãããåå2æã«æ¬çªç°å¢ã忢ããŸããéçºè ãAPIããŒãå¿ èŠãšããå ŽåãããããœãŒã¹ãã¡ã€ã«ã«å ¥åããã³ãããããŠããã·ã¥ããŸãã6ãæåŸããªããžããªãã¯ããŒã³ãããããŒããããªãã¯ãã©ãŒã¯ã«çŸããèª°ãæ°ã¥ããªããã¡ã«ã¢ã«ãŠã³ãã䟵害ãããŸãããããã¯äŸå€çãªã±ãŒã¹ã§ã¯ãããŸããããããã¯ããœãããŠã§ã¢ã·ã¹ãã ã«ãããããŒãã³ãŒããããå€ã®å žåçãªè»è·¡ã§ããäžèŠç¡å®³ã«èŠããæã£åãæ©ãæ¹æ³ããã¡ã³ããã³ã¹ã®è² æ ãã»ãã¥ãªãã£ã€ã³ã·ãã³ãããããã€ã¡ã³ãã®å€±æãžãšç©ã¿éãªã£ãŠããã®ã§ãã
ããŒãã³ãŒããããå€ãèŠã€ããŠåé€ãã
ããŒãã³ãŒãã£ã³ã°ãããå€ãæé€ãã
ãã£ãšè©³ããç¥ã解決çã¯è€éã§ã¯ãããŸãããç°å¢å€æ°ãèšå®ãã¡ã€ã«ãäŸåæ§æ³šå ¥ãéäžå®æ°ã¯ãäž»èŠãªããã°ã©ãã³ã°èšèªããã¬ãŒã ã¯ãŒã¯ã§åºãå©çšãããŠãããããç¥ããããã¿ãŒã³ã§ãã課é¡ã¯ãæ¢åã®ã³ãŒãããŒã¹å šäœã«ãããã®ãã¿ãŒã³ãäœç³»çã«é©çšããæ°èŠã³ãŒãã«ãé©çšã培åºãããæ¬çªç°å¢ã«å°éããåã«åé¡ãçºèŠããããã®èŠåŸã確ç«ããããšã§ãã以äžã§ã¯ãPythonãJavaãJavaScriptã®ã³ãŒãäŸã亀ããªããããããã®èª²é¡ã解決ããããã«å¿ èŠãªãã¹ãŠã®ãã¯ããã¯ã解説ããŸãã
ããŒãã³ãŒããããå€ãšã¯äœã§ããïŒ
ããŒãã³ãŒããããå€ãšã¯ãèšå®ãç°å¢å€æ°ãããŒã¿ããŒã¹ããŸãã¯å®è¡æå ¥åã«ãã£ãŠæäŸãããã®ã§ã¯ãªãããœãŒã¹ã³ãŒãã«çŽæ¥åã蟌ãŸãããªãã©ã«å®æ°ã®ããšã§ãããã®æ±ºå®çãªç¹åŸŽã¯éæ¥çãªåŠçããªãããšã§ããå€ã倿Žããããã«ãœãŒã¹ã³ãŒãã®å€æŽãåã³ã³ãã€ã«ããŸãã¯ã¢ããªã±ãŒã·ã§ã³ã®åãããã€ãå¿ èŠãªå Žåãããã¯ããŒãã³ãŒããããå€ã§ãã
äžè¬çãªäŸïŒ
- èšå®ã¯ã©ã¹ã«çŽæ¥å ¥åãããããŒã¿ããŒã¹æ¥ç¶æåå
- ãœãŒã¹ãã¡ã€ã«å ã®APIããŒãŸãã¯ã¢ã¯ã»ã¹ããŒã¯ã³
- ç¹å®ã®ç°å¢ãæããµãŒãã¹URL
- æ°å€ãããå€ïŒ
if (amount > 5000)説æãå€éšãœãŒã¹ãªã - ç¹å®ã®ãµãŒããŒã¬ã€ã¢ãŠããåæãšãããã¡ã€ã«ãã¹
- ãŠãŒã¶ãŒããŒã«æååïŒ
"admin"èªèšŒãã§ãã¯å šäœã«æ£åšããŠãã
ããŒãã³ãŒããããå€ã¯ãããããèšèªãããããã³ãŒãããŒã¹ã«ååšããŸããåŸæ¥ã®ã¡ã€ã³ãã¬ãŒã ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãç°å¢åºæã®ããŒã¿ã»ããåããªãŒãžã§ã³ã³ãŒããããžãã¹ãããå€ãCOBOLããã°ã©ã ã«çŽæ¥ãšã³ã³ãŒããããŠããŸãããææ°ã®ãã€ã¯ããµãŒãã¹ã§ã¯ãããŒãã³ãŒããããã¿ã€ã ã¢ãŠãå€ãå詊è¡åæ°ããµãŒãã¹æ€åºURLãã¢ããªã±ãŒã·ã§ã³ã¯ã©ã¹ã«èç©ãããŸãã圢åŒã¯èšèªã«ãã£ãŠç°ãªããŸãããåé¡ã¯åãã§ãã
ããŒãã³ãŒããããå€ãšå®æ°ïŒéãã¯äœã§ããïŒ
ããŒãã³ãŒããããå€ã¯å®æ°ãšæ··åãããã¡ã§ããããã®åºå¥ã¯éèŠã§ãã宿°ã¯ãå®çŸ©äžæ£ããã倿Žãããå¯èœæ§ãäœããå®å®ããæå³çãªãã¡ã€ã³ã¬ãã«ã®äºå®ã衚ããŸãã Math.PI, HTTP_STATUS_OK = 200, MAX_RETRY_ATTEMPTS = 3 ïŒãã3ãå
šãŠã®ç¶æ³ã«ãããŠæ¬åœã«æ£ããå ŽåïŒã宿°ã¯ã³ãŒãã«ãããŠé©åã§ãã宿°ã䜿ãããšã§ãã³ãŒãã®æçæ§ãåäžããã¿ã€ããã¹ãé²ããæå³ãæç¢ºã«ããããšãã§ããŸãã
ããŒãã³ãŒããããå€ã¯ãå±éã³ã³ããã¹ããã€ã³ãã©ã¹ãã©ã¯ãã£ããŸãã¯ããžãã¹ã«ãŒã«ã«é¢ããåææ¡ä»¶ããšã³ã³ãŒãããŠããããããã®åææ¡ä»¶ã¯å€åããããšãæ³å®ãããŸããæ¬çªããŒã¿ããŒã¹ã®URLãAPIããŒãå°ååºæã®çšçãæ©èœãã©ã°ã®ç¶æ ãªã©ã¯ã宿°ãè£ ã£ãããŒãã³ãŒããããå€ã§ãããã¹ãã¯ç°¡åã§ããç°ãªãç°å¢ã顧客ããŸãã¯ãªãªãŒã¹ã§å€ãç°ãªãå¿ èŠãããå Žåãããã¯å®æ°ã§ã¯ãªãããœãŒã¹ã³ãŒãã«å«ããã¹ãã§ã¯ãããŸããã
ãœããã³ãŒãã£ã³ã°ãšã¯äœã§ããïŒ
ãœããã³ãŒãã£ã³ã°ãšã¯ãã³ã³ãã€ã«æã«å€ãåºå®ããã®ã§ã¯ãªããå®è¡æã«èšå®å¯èœã«ããææ³ã§ãããœããã³ãŒãã£ã³ã°ãããå€ã¯ããœãŒã¹ã³ãŒãã倿Žãããã¢ããªã±ãŒã·ã§ã³ãåãããã€ãããããããšãªããèšå®ãã¡ã€ã«ãç°å¢å€æ°ãããŒã¿ããŒã¹ãšã³ããªããŸãã¯ç®¡çã€ã³ã¿ãŒãã§ãŒã¹ãéããŠå€æŽã§ããŸãããœããã³ãŒãã£ã³ã°ã¯ãç°å¢åºæã®èšå®ãããžãã¹ãã©ã¡ãŒã¿ãæ©èœãã©ã°ãããã³éçºç°å¢ãã¹ããŒãžã³ã°ç°å¢ãæ¬çªç°å¢éã§ç°ãªãå¿ èŠãããå¯èœæ§ã®ããããããå€ã«å¯ŸããŠé©åãªã¢ãããŒãã§ãã
ããŒãã³ãŒãã£ã³ã°ãšãœããã³ãŒãã£ã³ã°ã®éãã¯ãçšçãæŽæ°ããããã«ã³ãŒã倿Žãšãããã€ã¡ã³ããå¿ èŠãªã·ã¹ãã ãšãéçšããŒã ã®ã¡ã³ããŒãèšå®ãã¡ã€ã«ãæŽæ°ããŠãµãŒãã¹ãåèµ·åããã ãã§æžãã·ã¹ãã ã®éãã«çžåœããŸããå€§èŠæš¡ãªã·ã¹ãã ã§ã¯ããã®éãã¯æ°åæéãã®ãšã³ãžãã¢ã®äœæ¥æéãšé倧ãªéçšãªã¹ã¯ã«ã€ãªãããŸãã
ããŒãã³ãŒãã£ã³ã°ããªãæªãç¿æ £ãªã®ã
ä¿å®æ§ãæãªã
ããŒãã³ãŒããããå€ã¯å¢æ®ããŸãããããã¡ã€ã«ã«ããŒãã³ãŒãããããµãŒãã¹URLã¯ãã¢ãžã¥ãŒã«ãæ°ããçµ±åã®ããã«ã³ããŒããããšã5ã€ã®ãã¡ã€ã«ã«ããŒãã³ãŒããããããšã«ãªããŸããããèšç®åŒã«çŸããããžãã¯ãã³ããŒã¯ãåãããžãã¯ããããã«ç°ãªãã³ã³ããã¹ãã§è€è£œããããšã3ã€ã®èšç®åŒã«çŸããŸããããããã®ã€ã³ã¹ã¿ã³ã¹ã¯åå¥ã®ä¿å®çŸ©åãšãªããŸããã€ãŸããã€ã³ã¹ã¿ã³ã¹ãèŠã€ããæŽæ°ããæŽæ°ããã¹ãããã€ã³ã¹ã¿ã³ã¹ã®æŒãããªãããšãç¥ããããããŸããã
ä¿å®æ§ã®åé¡ã¯ãåã«åŽåã®åé¡ã ãã§ã¯ãããŸããããªã¹ã¯ã®åé¡ã§ããããŸããã³ãŒãããŒã¹å šäœã«ããã£ãŠããŒãã³ãŒããããå€ãæŽæ°ããããã®æ€çŽ¢çœ®æã¯ãæ¬çªç°å¢ã«åœ±é¿ãäžãããªãã¡ã¯ã¿ãªã³ã°æäœã§ããèŠèœãšããç®æãããã°ãã°ã§ãã誀ã£ã眮æããã°ã§ãã倿Žãå®äºããããšã確信ã§ããå¯äžã®æ¹æ³ã¯ãæ®ã£ãŠããç®æãããã°å€±æããèªåãã¹ããçšæããããšã§ãããããŒãã³ãŒããããå€ããããšããŸãã«èªåãã¹ãã®äœæãé£ãããªããŸãã
ãã¹ããšCI/CDãé»å®³ãã
èªåãã¹ãã¯ã管çãããç°å¢ã§å®è¡ããå¿ èŠããããŸããæ¥ç¶æååãããŒãã³ãŒããããŠããããã«æ¬çªããŒã¿ããŒã¹ã«æ¥ç¶ãããã¹ãã¯ããã¹ãã§ã¯ãªãããã«ãäžã«ããŸããŸå®è¡ãããæ¬çªæäœã§ããããŒãã³ãŒãããããµãŒãã¹URLããã«ããµãŒããŒããã¢ã¯ã»ã¹ã§ããªãããã«CIãã€ãã©ã€ã³ãäžæããã®ã¯ããã¹ãã€ã³ãã©ã¹ãã©ã¯ãã£ã®åé¡ã§ã¯ãªããããŒãã³ãŒãã£ã³ã°ã®åé¡ã§ãã
ç°å¢å€æ°ãšèšå®ã®æ³šå ¥ã¯ãç°ãªãããã¯ãšã³ããµãŒãã¹ã䜿çšããããŒã«ã«éçºç°å¢ãCIç°å¢ãã¹ããŒãžã³ã°ç°å¢ãæ¬çªç°å¢ãªã©ãããããç°å¢ã§åããã¹ãã¹ã€ãŒããå®è¡å¯èœã«ãããã®ã§ãããããããªããã°ããã¹ãã¯ç°å¢åºæã®ãã®ãšãªããäžå®å®ã«ãªããæçµçã«ã¯æŸæ£ãããŠããŸããŸãã
æ·±å»ãªã»ãã¥ãªãã£è匱æ§ãçã¿åºã
ããŒãã³ãŒããããèªèšŒæ å ±ã¯ããœãããŠã§ã¢ã»ãã¥ãªãã£ã«ãããŠæãäžè¬çã§ãæãæªçšãããããè匱æ§ã®äžã€ã§ããããŒãžã§ã³ç®¡çã·ã¹ãã ã«ã³ããããããããŒãã³ãŒããããAPIããŒãããŒã¿ããŒã¹ãã¹ã¯ãŒãããŸãã¯ã¢ã¯ã»ã¹ããŒã¯ã³ã¯ãçŸåšã®ãã©ã³ãããåé€ãããåŸããªããžããªã®å±¥æŽã«æ®ããŸããèªåã¹ãã£ããŒã¯ããããã®ãã¿ãŒã³ãç¶ç¶çã«ãããªãã¯ãªããžããªã§æ€çŽ¢ããŸãã18ãæåã®ã³ãããã§èŠã€ãã£ãããŒã¯ãäžåºŠãããŒããŒã·ã§ã³ãããŠããªããã°ãäŸç¶ãšããŠæå¹ã§ãã
OWASPã¯ãããŒãã³ãŒãããããã¹ã¯ãŒããé倧ãªã»ãã¥ãªãã£äžã®æ¬ é¥ïŒCWE-259ãCWE-798ïŒãšããŠæç¢ºã«ææããŠããŸããNISTã®ã¬ã€ãã©ã€ã³ã§ã¯ãèªèšŒæ å ±ããœãŒã¹ã³ãŒãã«ä¿åããŠã¯ãªããªããšèŠå®ãããŠããŸããã«ãããããããããŒãã³ãŒããããå€ãä»ããèªèšŒæ å ±ã®æŒæŽ©ã¯ãã¯ã©ãŠãã»ãã¥ãªãã£ã€ã³ã·ãã³ãã®æãäžè¬çãªåå ã®äžã€ãšãªã£ãŠããŸãã
ãªã¹ã¯ã¯èªèšŒæ å ±ã ãã«ãšã©ãŸããŸãããããŒãã³ãŒããããå éšãµãŒãã¹URLã¯ã€ã³ãã©ã¹ãã©ã¯ãã£ã®ããããžãŒãé²åããŸããããŒãã³ãŒãããããŠãŒã¶ãŒããŒã«æååã¯èªèšŒããžãã¯ãé²åããŸããããŒãã³ãŒããããæ€èšŒãããå€ã¯ãæ»æè ããã®æ£ç¢ºãªå€ãç¥ã£ãŠããã°åé¿å¯èœã§ãããããã¯ã©ããã»ãã¥ãªãã£ãªã¹ã¯ãšããŠããã«èªèã§ãããã®ã§ã¯ãªãããã察åŠãããªããŸãŸèç©ãããŠãããŸãã
ããŒãã³ãŒããããèªèšŒæ å ±ãšAPIããŒïŒæããªã¹ã¯ã®é«ãã«ããŽãª
ããŒãã³ãŒããããç§å¯æ å ±ã¯ããã®æ±ãã誀ã£ãå Žåã®çµæãä»ã®ããŒãã³ãŒãã£ã³ã°ã®åé¡ãšã¯æ ¹æ¬çã«ç°ãªããããç¹å¥ãªæ±ããå¿ èŠã§ããããŒãã³ãŒããããã¿ã€ã ã¢ãŠãå€ã¯ãã°ãåŒãèµ·ãããŸãããããŒãã³ãŒããããAPIããŒã¯æ å ±æŒæŽ©ã«ã€ãªãããŸãã
ããŒãã³ãŒããããèªèšŒæ å ±ã®äŸ
ãã€ãœã³
# Python -- hardcoded database credentials (never do this)
connection = psycopg2.connect(
host="prod-db.internal.example.com",
database="accounts",
user="app_service",
password="s3cr3tP@ssword!" # hardcoded secret in source code
)
# Python -- correct approach: load from environment
import os
connection = psycopg2.connect(
host=os.environ["DB_HOST"],
database=os.environ["DB_NAME"],
user=os.environ["DB_USER"],
password=os.environ["DB_PASSWORD"]
)
ãžã£ã¯
// Java -- hardcoded API key (never do this)
private static final String API_KEY = "sk-prod-a1b2c3d4e5f6g7h8i9j0";
// Java -- correct approach: load from environment
private static final String API_KEY = System.getenv("OPENAI_API_KEY");
ããŒãã³ãŒããããèªèšŒæ å ±ãä¿®æ£ããæ¹æ³
ç°å¢å€æ° ãããã¯ããããã€ãããã¢ããªã±ãŒã·ã§ã³ã«ãããã·ãŒã¯ã¬ããã®æšæºçãªãœãªã¥ãŒã·ã§ã³ã§ããã·ãŒã¯ã¬ããã¯ãããã€ç°å¢ïŒãµãŒããŒãã³ã³ãããKubernetesã·ãŒã¯ã¬ããããŸãã¯ã¯ã©ãŠãã·ãŒã¯ã¬ãããããŒãžã£ãŒïŒã«èšå®ãããå®è¡æã«ã¢ã¯ã»ã¹ãããŸãããœãŒã¹ã³ãŒãã«ã¯ã·ãŒã¯ã¬ããã®å€ã¯å«ãŸããŠããããååŸã«äœ¿çšãããããŒåã®ã¿ãèšè¿°ãããŠããŸãã
ç§å¯ç®¡çãµãŒãã¹AWS Secrets ManagerãHashiCorp VaultãAzure Key VaultãGoogle Secret Managerãªã©ã¯ããµãŒãã¹éã§ã·ãŒã¯ã¬ãããããŒããŒã·ã§ã³ãç£æ»ã忣ããããã®ãæ¬çªç°å¢ã¬ãã«ã®ãœãªã¥ãŒã·ã§ã³ã§ããã¢ããªã±ãŒã·ã§ã³ã¯ãç°å¢å€æ°ããã§ã¯ãªããèµ·åæïŒãŸãã¯å¿ èŠã«å¿ããŠïŒã«Vaultããã·ãŒã¯ã¬ãããååŸãããããåãããã€ãªãã§ããŒããŒã·ã§ã³ãå¯èœã«ãªãããã¹ãŠã®ã¢ã¯ã»ã¹ã«é¢ããå®å šãªç£æ»ãã°ãèšé²ãããŸãã
.env ãã¡ã€ã« ïŒæ¬¡ã®ãããªã©ã€ãã©ãªã䜿çšããïŒ python-dotenv or dotenv Node.js ã® `ç°å¢å€æ°` ã¯ããŒã«ã«éçºã«é©ããŠããŸããç°å¢å€æ°ãšåãã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãããããŒã«ã«ãã¡ã€ã«ããèªã¿èŸŒã¿ãŸããéèŠãªã«ãŒã«ã¯æ¬¡ã®ãšããã§ãã .env ãã¡ã€ã«ã¯ .gitignore ãããŠæ±ºããŠå®è¡ããŠã¯ãªããªãã
æ¢ã«å®è¡ãããç§å¯ãæ€åºãã: ç§å¯æ
å ±ãããŒãã³ãŒããããŠã³ããããããŠããå Žåãããã¯äŸµå®³ããããšã¿ãªãããçŽã¡ã«ããŒããŒã·ã§ã³ããå¿
èŠããããŸããçŸåšã®ãã©ã³ãããå€ãåé€ããŠããgit ã®å±¥æŽããã¯åé€ãããŸãããæ¬¡ã®ãããªããŒã« git-filter-branch ãŸãã¯ãBFG Repo Cleaner ã§å±¥æŽãåé€ããããšãã§ããŸãããã³ãããåŸã«ã¯ç§å¯æ
å ±ãæŒæŽ©ããŠãããšèããã®ãæãå®å
šã§ãã
ããŒãã³ãŒããããAPIããŒã鲿¢ããæ¹æ³
ãµãŒãããŒãã£APIããŒã®å ŽåãããŒãã³ãŒãã£ã³ã°ã®ä»£æ¿ææ®µã¯ç¶æ³ã«ãã£ãŠç°ãªããŸãã
- ãµãŒããŒåŽã¢ããªã±ãŒã·ã§ã³ç°å¢å€æ°ãŸãã¯ã·ãŒã¯ã¬ãã管çãµãŒãã¹
- CI / CDãã€ãã©ã€ã³ãã€ãã©ã€ã³ã®ã·ãŒã¯ã¬ãã倿°ïŒGitHub Actionsã®ã·ãŒã¯ã¬ãããGitLab CIã®å€æ°ïŒ
- ã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³APIããŒã¯ã¯ã©ã€ã¢ã³ãåŽã®ã³ãŒãã«æ±ºããŠå«ããŠã¯ãããŸããããµãŒããŒåŽã«ä¿åãããããŒã䜿çšããŠAPIãåŒã³åºãããã¯ãšã³ããããã·ã䜿çšããŠãã ããã
- AIãšãŒãžã§ã³ããšLLMã®çµ±åãšãŒãžã§ã³ãã®åæåæã«ç°å¢ããAPIããŒãèªã¿èŸŒã¿ãããã³ããã颿°åŒã³åºãã§ããŒãã³ãŒããããæååãšããŠæž¡ããªãã§ãã ããã
IBM i äžã® RPG ã»ãã¥ã¢ ã³ãŒãã£ã³ã°ãåãååã«åŸããŸããã€ãŸããç°å¢åºæã®æ¥ç¶ãã©ã¡ãŒã¿ã¯ãããã°ã©ã ãœãŒã¹ã«ãšã³ã³ãŒãããã®ã§ã¯ãªããå€éšããŒã¿é åãããŒã¿ ãã¥ãŒããŸãã¯ã·ã¹ãã å€ã«æ ŒçŽããå¿ èŠããããŸãã
ããŒãã³ãŒããããå€ã鲿¢ããæ¹æ³ïŒã³ãŒããå«ãå®å šãªãã¿ãŒã³
ç°å¢å€æ°
ç°å¢å€æ°ã¯æãæ±çšæ§ã®é«ã解決çã§ããäž»èŠãªãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãã¯ã©ãŠããã©ãããã©ãŒã ãã³ã³ããåã·ã¹ãã ãããã³ãããã€ã¡ã³ããã¬ãŒã ã¯ãŒã¯ã¯ãã¹ãŠç°å¢å€æ°ããµããŒãããŠããŸãã
ãã€ãœã³
# Python: load all configuration from environment
import os
from dotenv import load_dotenv
load_dotenv() # loads .env file in development; ignored in production
DATABASE_URL = os.environ["DATABASE_URL"]
API_BASE_URL = os.environ.get("API_BASE_URL", "https://api.example.com")
MAX_RETRIES = int(os.environ.get("MAX_RETRIES", "3"))
DEBUG_MODE = os.environ.get("DEBUG", "false").lower() == "true"
ãžã£ãã¹ã¯ãªãã
// Node.js: access environment variables
require('dotenv').config(); // load .env in development
const config = {
dbUrl: process.env.DATABASE_URL,
apiKey: process.env.API_KEY,
port: parseInt(process.env.PORT, 10) || 3000,
debug: process.env.NODE_ENV !== 'production',
};
ãžã£ã¯
// Java: environment variables via System.getenv()
public class AppConfig {
public static final String DB_URL = System.getenv("DATABASE_URL");
public static final String API_KEY = System.getenv("THIRD_PARTY_API_KEY");
public static final int TIMEOUT = Integer.parseInt(
Optional.ofNullable(System.getenv("REQUEST_TIMEOUT_MS")).orElse("5000")
);
}
æ§æãã¡ã€ã«
èšå®ãã¡ã€ã«ã¯ãç°å¢åºæã§ã¯ãããæ©å¯ã§ã¯ãªãå€ããµãŒãã¹åãæ©èœãã©ã°ãããŒãžããŒã·ã§ã³ãµã€ãºããã£ãã·ã¥ã®æå¹æéãªã©ãå€éšåããŸãã
ã€ã ã«
# config/production.yaml
database:
host: prod-db.internal
port: 5432
pool_size: 20
api:
base_url: https://api.partner.com/v2
timeout_ms: 3000
max_retries: 3
features:
new_checkout: true
beta_dashboard: false
ãã€ãœã³
# Load at startup; never hardcode the values it contains
import yaml
with open(f"config/{os.environ['APP_ENV']}.yaml") as f:
config = yaml.safe_load(f)
timeout = config["api"]["timeout_ms"]
äŸåæ§æ³šå ¥
äŸåæ§æ³šå ¥ã§ã¯ãã³ã³ããŒãã³ããç¬èªã®æ§æãäœæãŸãã¯ååŸããã®ã§ã¯ãªããæ§ææžã¿ã®å€ãã³ã³ããŒãã³ãã«æž¡ããŸããããã«ãããã³ã³ããŒãã³ããåå¥ã«ãã¹ãããããç°å¢ããšã«æ§æãããããããšãå¯èœã«ãªããŸãã
ãžã£ã¯
// Spring Boot: inject configuration via @Value
@Service
public class PaymentService {
@Value("${payment.api.url}")
private String apiUrl;
@Value("${payment.api.timeout-ms}")
private int timeoutMs;
// No hardcoded URL or timeout anywhere in this class
public PaymentResult process(Payment payment) {
// uses apiUrl and timeoutMs injected from application.properties
}
}
ãã€ãœã³
# Python: simple constructor injection
class EmailService:
def __init__(self, smtp_host: str, smtp_port: int, api_key: str):
self.smtp_host = smtp_host
self.smtp_port = smtp_port
self.api_key = api_key
# Wire at application startup, reading from environment
email_service = EmailService(
smtp_host=os.environ["SMTP_HOST"],
smtp_port=int(os.environ["SMTP_PORT"]),
api_key=os.environ["EMAIL_API_KEY"],
)
éäžç®¡çããã宿°ãšåæå
èšèšäžåºå®ãããŠããå€ãHTTPã¹ããŒã¿ã¹ã³ãŒãããã¡ã€ã³åºæã®ç¶æ ããããã³ã«èå¥åãªã©ã¯ãæååãªãã©ã«ãšããŠæ£åšãããã®ã§ã¯ãªããåäžã®ååä»ã宿°ã¢ãžã¥ãŒã«ã«ãŸãšããã¹ãã§ãã
ãã€ãœã³
# Python: centralised constants
from enum import Enum
class OrderStatus(Enum):
PENDING = "pending"
CONFIRMED = "confirmed"
SHIPPED = "shipped"
DELIVERED = "delivered"
CANCELLED = "cancelled"
# Usage: no magic strings scattered across modules
if order.status == OrderStatus.CONFIRMED:
notify_warehouse(order)
ãžã£ã¯
// Java: enum with business meaning
public enum UserRole {
ADMIN("admin"),
EDITOR("editor"),
VIEWER("viewer");
private final String value;
UserRole(String value) { this.value = value; }
public String getValue() { return value; }
}
// Replaces scattered "admin", "editor", "viewer" strings
if (user.getRole() == UserRole.ADMIN) {
grantFullAccess(user);
}
ç¹å®ã®èšèªã§ã®ããŒãã³ãŒãã£ã³ã°
Pythonã«ãããããŒãã³ãŒãã£ã³ã°ãšã¯äœã§ããïŒ
Python ã§ã¯ãããŒãã³ãŒãã£ã³ã°ã¯ãURL ãèªèšŒæ
å ±ã«å¯Ÿããæååãªãã©ã«ãããžãã¹ããžãã¯å
ã®æ°å€å®æ°ãç¹å®ã®ãã£ã¬ã¯ããªæ§é ãåæãšãããã¡ã€ã«ãã¹ãšããŠæãäžè¬çã«èŠãããŸãã os.environ and python-dotenv ç°å¢ããŒã¹ã®èšå®ã®ããã®æšæºçãªã¡ã«ããºã ã§ãã configparser ãã®ã¢ãžã¥ãŒã«ã¯INI圢åŒã®èšå®ãã¡ã€ã«ãåŠçããŸãã pydantic-settings ç°å¢å€æ°ããããã©ã«ãå€ä»ãã®åæ€èšŒæžã¿èšå®ãæäŸããŸããããã¯ãæ¬çªç°å¢ã®PythonãµãŒãã¹ã§æšå¥šãããæ¹æ³ã§ãã
Pythonã«ãããããŒãã³ãŒããããå€ã®æ€åºïŒBanditïŒãã¹ã¯ãŒããããŒãªã©ã®ã»ãã¥ãªãã£é¢é£ã®ããŒãã³ãŒãçšïŒãPylintãSemgrepãªã©ã®éçè§£æããŒã«ã¯ãããŒãã³ãŒããããèªèšŒæ å ±ãããžãã¯ãã³ããŒãèªåçã«èå¥ã§ããŸãã
Javaã«ãããããŒãã³ãŒãã£ã³ã°ãšã¯äœã§ããïŒ
Javaã§ã¯ãããŒãã³ãŒããããå€ã¯ãã°ãã°æ¬¡ã®ããã«è¡šç€ºãããŸãã private static final String ãã£ãŒã«ãã @Value ã€ã³ã©ã€ã³ããã©ã«ãå€ãæã€ã¢ãããŒã·ã§ã³ã¯å€éšåãããã¹ãã§ãããããžãã¹ããžãã¯å
ã®ãªãã©ã«ãåæ§ã§ãããSpring Bootã® application.properties and application.yml ãã¡ã€ã«ã¯æšæºçãªå€éšåã¡ã«ããºã ã§ããã @ConfigurationProperties-泚éä»ãã¯ã©ã¹ã¯ãYAMLãã¡ã€ã«ãŸãã¯ããããã£ãã¡ã€ã«ããåå®å
šã§æ€èšŒæžã¿ã®èšå®ãªããžã§ã¯ããæäŸããŸãã
Javaã«ãããããŒãã³ãŒããããå€ã®æ€åºïŒSpotBugsã®ãã»ãã¥ãªãã£ãã°æ€åºããã©ã°ã€ã³ã¯ãããŒãã³ãŒããããèªèšŒæ å ±ãæ€åºããŸããSonarQubeã¯ãããžãã¯ãã³ããŒãããŒãã³ãŒããããURLãããã³ããŒãã³ãŒãããããã¹ã¯ãŒããæ€åºããŸãã SMART TS XLã®ãšã³ã¿ãŒãã©ã€ãºåæã¯ãJavaã³ãŒãããŒã¹ã«å ããCOBOLããã®ä»ã®ã¬ã¬ã·ãŒèšèªã察象ãšããŠããŸãã
ã¬ã¬ã·ãŒã³ãŒããšã¡ã€ã³ãã¬ãŒã ã³ãŒãã«ãããããŒãã³ãŒãã£ã³ã°
IBMã¡ã€ã³ãã¬ãŒã ããã³ãããã¬ã³ãžã·ã¹ãã äžã®COBOLãRPGãPL/Iããã°ã©ã ã«ã¯ãDDã¹ããŒãã¡ã³ãã«åã蟌ãŸããããŒã¿ã»ããåãããã°ã©ã ããžãã¯å ã®ç°å¢èå¥åãããã°ã©ã ã«çŽæ¥ã³ã³ãã€ã«ãããããžãã¹ãããå€ãªã©ãç¹å®ã®ããŒãã³ãŒãã£ã³ã°ãã¿ãŒã³ãååšããŸãããããã®å€ãå€éšåããã«ã¯ãã·ã¹ãã ãã©ã¡ãŒã¿ïŒSYSPARMïŒãå€éšããŒã¿é åãDB2ã®æ§æããŒãã«ããã©ã¡ãŒã¿åãããJCLãªã©ãã¡ã€ã³ãã¬ãŒã ã«å¯Ÿå¿ããããŒã«ãå¿ èŠã§ãããããã®ãã¿ãŒã³ãå€§èŠæš¡ã«æ€åºããã«ã¯ãã¡ã€ã³ãã¬ãŒã èšèªãçè§£ããéçè§£æããŒã«ãäžå¯æ¬ ã§ãã
å®äžçã®ã³ãŒããªãã¡ã¯ã¿ãªã³ã°ïŒããŒãã³ãŒãã£ã³ã°ããèšå®å¯èœãž
3段éãªãã¡ã¯ã¿ãªã³ã°ã¢ãããŒã
ãã§ãŒãº1ïŒçºèŠã ã³ãŒãããŒã¹å šäœã«å¯ŸããŠéçè§£æãå®è¡ããããŒãã³ãŒããããå€ã®ã€ã³ãã³ããªãäœæããŸãããã®ã€ã³ãã³ããªã¯ãã¿ã€ãïŒèªèšŒæ å ±ãURLãããžãã¹ããžãã¯ãããžãã¯ãã³ããŒïŒãšãªã¹ã¯ã¬ãã«ããšã«ã°ã«ãŒãåãããŸããèªèšŒæ å ±ãšæ¬çªç°å¢åºæã®å€ã«ã¯åªå é äœãä»ããŸãã
ãã§ãŒãº2ïŒã«ããŽãªãŒå¥ã«å€éšåããã ãŸããèªèšŒæ å ±ïŒæããªã¹ã¯ãé«ãïŒããçæããŸãããã¹ãŠã®æ©å¯æ å ±ãç°å¢å€æ°ãŸãã¯ã·ãŒã¯ã¬ãããããŒãžã£ãŒã«ç§»åããŸããæ¬¡ã«ãç°å¢åºæã®URLãšãµãŒãã¹åã«å¯ŸåŠããŸãããã®åŸãããžãã¹ããžãã¯ã®ãããå€ã«å¯ŸåŠããŸããæåŸã«ãããžãã¯ãã³ããŒãååä»ã宿°ãŸãã¯æ§æå€ã«çœ®ãæããããšã§å¯ŸåŠããŸãã
ãã§ãŒãº3ïŒå®æœã CIãã€ãã©ã€ã³ã«ãæ°ãã«ããŒãã³ãŒããããèªèšŒæ å ±ã«å¯ŸããŠãšã©ãŒãšãªãéçè§£æãã§ãã¯ã远å ããŸããããžãã¯ãã³ããŒãæ€åºãããªã³ãã£ã³ã°ã«ãŒã«ã远å ããŸããã³ãŒãã¬ãã¥ãŒãã§ãã¯ãªã¹ãé ç®ã远å ããŸããç®æšã¯ãããŒãã³ãŒããããå€ã远å ããããããæ£ãããã¿ãŒã³ã䜿çšããæ¹ãç°¡åã«ãªãããã«ããããšã§ãã
ã¬ã¬ã·ãŒãããžã§ã¯ãã«ãããããŒãã³ãŒããããå€ã®ç¹å®
é·å¹Žã«ããã£ãŠããŒãã³ãŒããããå€ãèç©ãããŠããã¬ã¬ã·ãŒãããžã§ã¯ãã§ã¯ã次ã®ããã«ãªããŸãã
- ã
grepãŸãã¯ãªããžããªæ€çŽ¢ã§å ±éãã¿ãŒã³ãæ€çŽ¢:æ¥ç¶æååãpassword,apikeyIPã¢ãã¬ã¹ãã¿ãŒã³ãããã³ããç¥ããããµãŒãã¹å - éçè§£æããŒã« (BanditãSonarQubeãSemgrepã SMART TS XLæåã§ãã¡ã€ã«ããšã«ç¢ºèªããããšãªããå®å šãªåšåº«ãªã¹ããååŸãã
- 以åã³ãããããåé€ãããã·ãŒã¯ã¬ããã«ã€ããŠã¯ãGitã®å±¥æŽã確èªããŠãã ããããããã¯ãªããžããªã®å±¥æŽããåŒãç¶ãã¢ã¯ã»ã¹ã§ããŸãã
- è€æ°ã®ãã¡ã€ã«ã«åãå€ãååšããå Žåããããã¯äžå åã®åè£ãšãªããŸãã
ããŒãã³ãŒããããå€ãå°å ¥ãããã®ãé²ã
- ã³ãããåã®ããã¯: è³æ Œæ
å ±ã¹ãã£ã³ãå®è¡ããŸã (äŸ:
detect-secrets,git-secrets,truffleHogïŒãªããžããªã«å°éããåã«ãã¹ãŠã®ã³ãããã«å¯Ÿã㊠- CIãã€ãã©ã€ã³ã²ãŒã: æ°ãã«å°å ¥ãããèªèšŒæ å ±ãŸãã¯ããžãã¯ãã³ããŒã«é¢ããéçè§£æçµæãå«ããã«ãã倱æããã
- ã³ãŒãã¬ãã¥ãŒãã§ãã¯ãªã¹ãããŒã ã®ã¬ãã¥ãŒããã»ã¹ã«ãããèšå®ã®å€éšåã«é¢ããæç€ºçãªé ç®
- éçºè
ãªã³ããŒãã£ã³ã°: æ£ãããã¿ãŒã³ãããã©ã«ãã«ããç°å¢å€æ°ãš
.env.examplefile
èªå®æ¡ä»¶ SMART TS XL å€§èŠæš¡ãªããŒãã³ãŒãå€ãæé€
å°èŠæš¡ãªã³ãŒãããŒã¹ã§ããã°ãæåæ€çŽ¢ãgrepã§æãããªããŒãã³ãŒãç®æãèŠã€ããã®ã¯ååã§ããããããCOBOLãJavaãPythonã.NETãRPGãSQLãªã©ãæ°çŸäžè¡ã«åã¶ãšã³ã¿ãŒãã©ã€ãºã·ã¹ãã ã§ã¯ãå æ¬çãªããŒãã³ãŒãå€ã®æ€åºã«ã¯èªååãããæ§é åæãå¿ èŠã§ãã SMART TS XL ãããã®èšèªãã¹ãŠã«å¯ŸããŠåæã«éçè§£æãå®è¡ãã以äžãèå¥ããçµ±äžãããçžäºåç §ã¢ãã«ãæ§ç¯ããŸãã
- æ¥ç¶ãã©ã¡ãŒã¿ããã³èªèšŒåŒã³åºãã«ããããªãã©ã«æååå€ã¯ãæœåšçãªèªèšŒæ å ±æŒæŽ©ãšããŠãã©ã°ä»ããããŠããŸãã
- ããžãã¹ããžãã¯å ã®ããžãã¯ãã³ããŒãæ§æå¯èœãªããŒã¹ã©ã€ã³ãšæ¯èŒããã¢ãžã¥ãŒã«éã§äžè²«æ§ã®ãªãå€ããç°ãªãå Žæã§ç°ãªãå€ã瀺ãå€ãç¹å®ããŸãã
- è€æ°ã®ãã¡ã€ã«ã«ãŸããã£ãŠåºçŸãããã®ã®ãè«ççã«åãç®çãæããéè€ãããªãã©ã«å€ã¯ãäžå åã®æ©äŒã瀺åããŠããã
- COBOLããã°ã©ã ã«ãããç°å¢åºæã®èå¥åããšã³ã³ãŒãããå€ã¯ãéåžžJCLãã©ã¡ãŒã¿ãéããŠç®¡çãããã
- ãªãã¡ã¯ã¿ãªã³ã°ã®æ±ºå®ãè¡ãåã«ãããŒãã³ãŒããããå€ããã·ã¹ãã å šäœãžã®ããŒã¿ãããŒãã¹ã瀺ããã©ã®äžæµæäœããããã«äŸåããŠãããã瀺ããŸãã
ãã® éçã³ãŒãåæ æ©èœã¯åšåº«ãæäŸããŸãã 圱é¿åæ æ©èœã¯ãããŒãã³ãŒããããå€ã眮ãæãããããšãã«äœã圱é¿ãåãããã瀺ããŸãã ã¬ã¬ã·ãŒã®è¿ä»£å ãã®æ©èœã¯ãåãè«çå€ãã¡ã€ã³ãã¬ãŒã ããã°ã©ã ãšJavaãµãŒãã¹ã«ããããç¬ç«ããŠããŒãã³ãŒãã£ã³ã°ãããŠãããããªãèšèªããã©ãããã©ãŒã ãè·šãã ã·ããªãªã«ãé©çšãããåå¥ã®ä¿®æ£ã§ã¯ãªãã飿ºãã修埩ãå¿ èŠãšãªããŸãã
ç¹ã«ã»ãã¥ãªãã£è² åµã管çããããŒã ã«ãšã£ãŠã SMART TS XLã®ããŒãã³ãŒããããèªèšŒæ å ±ã®æ€åºæ©èœã¯ããã«ãã²ãŒããšããŠCI/CDãã€ãã©ã€ã³ã«çµ±åãããŸããããŒãã³ãŒããããç§å¯æ å ±ãå°å ¥ããæ°ããã³ãããã¯ãã³ãŒããå ¬éãããå¯èœæ§ã®ãããªããžããªã«å°éããåã«ããã«ããèªåçã«å€±æãããŸãã
ããŒãã³ãŒãã£ã³ã°ã¯ç¥èã®åé¡ã§ã¯ãªããèŠåŸã®åé¡ã§ãã
å€ãããŒãã³ãŒãã£ã³ã°ããéçºè ã®ã»ãšãã©ã¯ããããã¹ãã§ã¯ãªãããšãæ¿ç¥ããŠãããç°å¢å€æ°ãååšããããšãèšå®ãã¡ã€ã«ãæ£ããæ¹æ³ã§ããããšãèªèšŒæ å ±ããœãŒã¹ã³ãŒãã«å«ããŠã¯ãªããªãããšã¯ãåºãç¥ãããåºãçè§£ãããŠãããåé¡ã¯ç¥èäžè¶³ã§ã¯ãªãããã¬ãã·ã£ãŒã®äžã§èŠåŸãå®ããªãããšã«ããã
çŽæãè¿«ã£ãŠãããšãç°å¢å€æ°ã®èšå®ãé¢åã«æãããããã¬ã¬ã·ãŒã³ãŒãããŒã¹ã§ã¯ãå€ããã®ãŸãŸã«ããŠãããããå€éšåã®æ¹ããªã¹ã¯ãé«ãããã«æããããªã³ããŒãã£ã³ã°ãäžååãªå€§èŠæš¡ããŒã ã§ã¯ãæ°äººéçºè ãæ¢åã®ééã£ããã¿ãŒã³ã宿ã«ã³ããŒããŠããŸãå¯èœæ§ãããããããã£ãŠãçµç¹èŠæš¡ã§ããŒãã³ãŒãã£ã³ã°ã«å¯ŸåŠããã«ã¯ãããã¥ã¡ã³ãäœæä»¥äžã®ãã®ãå¿ èŠãšãªããééã£ããã¿ãŒã³ãæ£ãããã¿ãŒã³ãããé£ãããªããããªãèªååãããåŒ·å¶æªçœ®ãå¿ èŠãªã®ã ã
æ©å¯æ å ±ãå«ãã³ããããæåŠããããªã³ãããããã¯ãæ°ããããžãã¯ãã³ããŒã§å€±æããCIãã€ãã©ã€ã³ãèšå®ã®å€éšåã«ã€ããŠæç€ºçã«è³ªåããã³ãŒãã¬ãã¥ãŒãã§ãã¯ãªã¹ããã³ãŒãããŒã¹å ã®æ¢åã®ããŒãã³ãŒããããå€ã®å šç¯å²ãæããã«ããéçè§£æããŒã«ããããã¯ãæ£ããã¢ãããŒããç¥ãããšãšããããäžè²«ããŠé©çšããããšã®éã®ã®ã£ãããåããã¡ã«ããºã ã§ãããã®èšäºã®ã³ãŒãäŸãšãã¿ãŒã³ã¯ãæè¡çãªåºç€ãæäŸããŸãããããŠãããããå®çãããã®ã¯ã匷å¶ã¡ã«ããºã ãªã®ã§ãã