The agreement will allow millions of tonnes of grain, currently trapped in Ukraine by the war, to be exported.
The world shortage of Ukrainian grain since Russia's 24 February invasion has left millions at risk of hunger.
However, Kyiv refused to sign a direct deal with Moscow, and warned "provocations" would be met with "an immediate military response".
Both sides attended the signing ceremony in Istanbul but did not sit at the same table. Russia's Defence Minister Sergei Shoigu signed Moscow's deal first, followed by Ukrainian Infrastructure Minister Oleksandr Kubrakov signing Kyiv's identical agreement.
The deal - which took two months to reach - is set to last for 120 days, with a co-ordination and monitoring centre to be established in Istanbul, staffed by UN, Turkish, Russian and Ukrainian officials. It can be renewed if both parties agree.
The blockade of Ukraine's grain has caused a global food crisis with wheat-based products like bread and pasta becoming more expensive, and cooking oils and fertiliser also increasing in price.
The US called on Russia to act quickly, with White House spokesman John Kirby saying it was necessary "to prevent the world's most vulnerable from sliding into deeper insecurity and malnutrition".